You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm encountering the same issue as described in #392 where Received.InOrder evaluates argument matchers at assertion time rather than at the time of the actual call. This leads to false negatives when testing with mutable objects that change during the test.
Consider this example:
varaction=Substitute.For<IAction>();varperson=newPerson(){Name="John"};action.Act(person);person.Name="Doe";action.Act(person);person.Name="Hans";// This fails because both calls are evaluated with person.Name == "Hans"Received.InOrder(()=>{action.Act(Arg.Is<Person>(p =>p.Name=="John"));action.Act(Arg.Is<Person>(p =>p.Name=="Doe"));});
In my case, the argument matchers are far more complex than in this simplified example, making workarounds like capturing the state manually impractical.
Describe the solution you'd like
I've started developing a solution like this:
varaction=Substitute.For<IAction>();varperson=newPerson(){Name="John"};// Configure expectations before any calls happenvarverifier=WillReceive.InOrder(action,
desc =>{desc.Call(x =>x.Act(Arg.Is<Person>(p =>p.Name=="John")));desc.Call(x =>x.Act(Arg.Is<Person>(p =>p.Name=="Doe")));});// Each call will be verified in the order it was received.// If there were any calls skipped, an exception will be thrown.action.Act(person);person.Name="Doe";action.Act(person);person.Name="Hans";// Are any calls missing at the end of the test?verifier.Verify();
The core concept is to register the expected calls beforehand and use NSubstitute's .When().Do() to immediately evaluate each call as it happens, storing just a simple boolean result rather than capturing or cloning the arguments. The approach provides reliable verification of mutable objects while completely avoiding the serialization concerns raised in #392 .
I've started building this as a separate utility that works around NSubstitute, but I believe it would be much more valuable as a native feature. The concept is flexible enough to support various verification scenarios while maintaining the simple and intuitive API style of NSubstitute.
I'd be happy to contribute this as a pull request once the design is agreed upon and would appreciate feedback on whether this approach aligns with NSubstitute's philosophy and any suggestions for better integration with the existing codebase.
The text was updated successfully, but these errors were encountered:
Is your feature request related to a problem?
I'm encountering the same issue as described in #392 where
Received.InOrder
evaluates argument matchers at assertion time rather than at the time of the actual call. This leads to false negatives when testing with mutable objects that change during the test.Consider this example:
In my case, the argument matchers are far more complex than in this simplified example, making workarounds like capturing the state manually impractical.
Describe the solution you'd like
I've started developing a solution like this:
The core concept is to register the expected calls beforehand and use NSubstitute's
.When().Do()
to immediately evaluate each call as it happens, storing just a simple boolean result rather than capturing or cloning the arguments. The approach provides reliable verification of mutable objects while completely avoiding the serialization concerns raised in #392 .I've started building this as a separate utility that works around NSubstitute, but I believe it would be much more valuable as a native feature. The concept is flexible enough to support various verification scenarios while maintaining the simple and intuitive API style of NSubstitute.
I'd be happy to contribute this as a pull request once the design is agreed upon and would appreciate feedback on whether this approach aligns with NSubstitute's philosophy and any suggestions for better integration with the existing codebase.
The text was updated successfully, but these errors were encountered: