FakeItEasy: Identify precise mismatch when a complex argument constraint fails to match an argument
From http://stackoverflow.com/a/43781563/131809
Consider the following assertion
var fake = A.Fake<ICustomerService>();
A.CallTo(() => fake.Add(
A<Customer>.That.Matches(c =>
c.Property == "123" &&
c.OtherProperty == "345" &&
c.AnotherProperty == "456" &&
c.YetAnotherProperty == "567"
)
)).MustHaveHappened();
This gets a bit messy.
If c.AnotherProperty
is infact “890” my unit test will not tell me.
It won’t tell me that AnotherProperty
is wrong. It’ll just fail (correctly)
To work around this, I quite often do this:
var fake = A.Fake<ICustomerService>();
Customer addedCustomer;
A.CallTo(() => fake.Add(A<Customer>._))
.Invokes(c => addedCustomer = c.GetArgument<Customer>(0));
Assert.IsNotNull(addedCustomer);
Assert.AreEqual("123", addedCustomer.Property);
Assert.AreEqual("345", addedCustomer.OtherProperty);
Assert.AreEqual("456", addedCustomer.AnotherProperty);
Assert.AreEqual("567", addedCustomer.YetAnotherProperty);
I guess it’d be nice if the exception MustHaveHappened
throws if the matcher does not validate, somehow includes which property or properties didn’t match
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Comments: 26 (21 by maintainers)
@alexjamesbrown, thanks for making this.
I may be missing something, but are not the calls output when
MustHaveHappened
fails to match? e.g.If you can’t tell what’s wrong, have you considered augmenting the
Customer
rendering? Either a ToString or an ArgumentValueFormatter likeyields
Given the complexity of implementing a solution where the particular failing clause is pinpointed, as well as the potential expansion of the error messages (as we’d have to indicate for each argument of each call which clause of the matcher failed), I propose that we close this wont-fix.
Objections?
Scratch that. There’s an extension method that takes an
Expression<Func<T, bool>>
, so we could do just this: