AllSatisfy()
fails on empty collections
#2143
Replies: 8 comments 7 replies
-
This most likely falls under "design choice". Do you have a more realistic example where this is a problem for you? |
Beta Was this translation helpful? Give feedback.
-
Exactly. If your test is expecting an empty collection, make that explicit. I can't imagine a test that sometimes expects an empty collection and sometimes a collection which items match the predicates. |
Beta Was this translation helpful? Give feedback.
-
In fact, I came across this bug because I had made a parameterized test that would check required properties of the result. Initially, I had just given nontrivial test case input (producing among other objects a nonempty list), but the code should also work for trivial input (producing among other objects an empty list), and the same properties should still apply for the result. When I added the trivial test case, the test failed. I was in fact surprised that If you have a need for ensuring a nonempty list as well as a property on each element, I would expect you could do something like .Should().NotBeEmpty().And.AllSatisfy(...) making your intention clear and explicit. Note that I am not able to fluently assert "empty or all satisfy" using If you really want to compound the two tests into a single method, I suggest adding a new method |
Beta Was this translation helpful? Give feedback.
-
In trying to understand you case, I have to ask: why would you want to test a vacuous truth? From #1492
Conversely I don't think most developers are mathematicians. From the wiki-page
That's selection bias, people don't raise issues with things that works fine 🙃 |
Beta Was this translation helpful? Give feedback.
-
OK, this is frustrating, and seems to lead to nowhere. I don't find it ureasonable to want to test "no matter how many elements there might be in a result, xs, they should all satisfy P(x)." In parameterized DRY test methods you can easily end up testing results that for some test cases (i.e., parameter sets) are trivial (i.e., zero, empty, null, etc.). If, for instance, you were to test the [Theory]
[MemberData("FilterTestCases")]
public void FilterTest(List<int> xs, Func<int, bool> p) {
var rs = xs.Filter(p).ToList();
rs.AllSatisfy(r => p(r));
}
public static object[][] FilterTestCases { get; } = new object[][] {
new object[] { new List<int>(), x => x > 3 },
new object[] { new List<int>{ 1, 2, 3, 4, 5 }, x => x > 3 },
...
} Constructively, I suggest either
The attractiveness of FluentAssertions is that it is fluent and orthogonal, so that we can naturally express and combine all our assertions within the framework without using C# control statements like The current semantics of |
Beta Was this translation helpful? Give feedback.
-
Although you're not wrong, we often have to deal with trade-offs where opinions can differ wildly. In those cases, we sometimes ask the community to provide us with feedback. Now, when I see a statement like:
Then there would not a doubt in my mind that I agree that the documentation should be clearer, but even if you would convince us that your concerns are valid, it would still be a breaking change. And that would probably require revisiting all similar APIs and create a lot of confusion for people upgrading.. |
Beta Was this translation helpful? Give feedback.
-
I too find the "fail on empty" behavior on Firstly, the current behavior goes against existing abstractions. For example, LINQ's
(Emphasis mine.) The same point applies to F#'s Secondly, checking for non-emptiness and checking whether all elements satisfy a predicate are two orthogonal concepts. Thirdly, if users additionally wish to check that a collection is non-empty, that can be done using With all of the above in mind, I strongly suggest that the design decision be reevaluated, at least for the next major version. |
Beta Was this translation helpful? Give feedback.
-
We ran into this issue in one of our tests while migrating from The system-under-test generates a date range series and this particular test is parameterized. It's written in a way that all the inner date ranges are verified with the same assertion ( |
Beta Was this translation helpful? Give feedback.
-
Description
new object[0].Should().AllSatisfy(o => { });
fails withThis does not implement the documented effect of
AllSatisfy
:In particular, any empty collection should always pass this test.
The bug is probably due to two code lines in
fluentassertions/Src/FluentAssertions/Collections/GenericCollectionAssertions.cs
Lines 2929 to 2930 in c3b9a70
Reproduction Steps
Expected behavior
The test should pass without throwing an exception.
Actual behavior
The test fails with exception
Regression?
This has probably always been this way.
Known Workarounds
Code like this would be a workaround:
However, reading the documentation of
.AllSatisfy()
, it should not be necessary.Configuration
FluentAssertions 6.9.0
.NET 6.0
Other information
The WikiPedia article on universal quantification states that
so it is the documentated behaviour of
.AllSatisfy()
that is conventionally correct, and the implementation that is not.Beta Was this translation helpful? Give feedback.
All reactions