dart-lang / test

A library for writing unit tests in Dart.
https://pub.dev/packages/test
497 stars 214 forks source link

Add an "exactlyOneOf" matcher #2343

Open nex3 opened 9 years ago

nex3 commented 9 years ago

Sometimes it's useful to say that exactly one of a set of matchers matches. We should have a matcher that supports this.

srawlins commented 6 years ago

+1; I'll just note my use case: I have a code that results in a List of two objects:

So I can't use contains, and pre-mapping to members plus contains is kludgey and imprecise:

expect(myList.map((e) => e.member1), contains('m1a'));
expect(myList.map((e) => e.member1), contains('m1b'));
expect(myList.map((e) => e.member2), contains('m2a'));
expect(myList.map((e) => e.member2), contains('m2b'));

Mapping to member values and using unorderedEquals is closer to what the developer is trying to express, but is also kludgey:

expect(myList.map((e) => e.member1), unorderedEquals(['m1a', 'm1b']);
expect(myList.map((e) => e.member2), unorderedEquals(['m2a', 'm2b']);

And again, that is imprecise, because the objects might be ('m1a', 'm2b') and ('m1b', 'm2a'), which passes the expectations, but is NOT a correct result. So then it gets even zanier:

expect(myList.singleWhere((e) => e.member1 == 'm1a').mebmer2, equals('m2a'));
expect(myList.singleWhere((e) => e.member1 == 'm1b').mebmer2, equals('m2b'));

This is undesirable, because if the test fails to find a singleWhere member1 == 'm1a', the code will just throw an error, rather than a test failure. ☹️