NSubstitute and equivalency argument matching
When using the otherwise superb NSubstitute, one thing has been bothering me for a long time: you cannot match arguments by equivalency.
To illustrate what I mean, let’s use an example. Say you got the following interface
1 | public interface ISomeInterface |
and a method that does something with it (for the sake of the example):
1 | static void DoSomethingWith(ISomeInterface service) |
Now how would you test that method? You’d start with the following:
1 | var service = Substitute.For<ISomeInterface>(); |
But now you’d like to validate that service.Use()
was called with the right Person
. Because NSubstitute has no built-in equivalency argument matcher, you would have to do this:
1 | service.Received().Use(Arg.Is<Person>(p => p.FirstName=="John" && p.LastName=="Doe" && p.Birthday==new DateTime(1968, 6, 1)); |
but obviously that is rather tedious and becomes unmanageable with more properties in Person
.
Alternatively, you can do:
1 | var service = Substitute.For<ISomeInterface>(); |
This approach uses FluentAssertions and is a lot more robust, but it doesn’t make for easy reading.
Solution
Ideally, one would like to just write:
1 | var service = Substitute.For<ISomeInterface>(); |
And if you install NSubstitute.Equivalency, a little helper library I wrote for this purpose, you can do just that.
I called the type for accessing this matcher ArgEx
to avoid creating import conflicts with the standard NSubstitute Arg
type.