NSubstitute
NSubstitute copied to clipboard
Create a spy of Func<> and make it return a specific value for testing
Question Hi all,
Been bashing my head against a desk on this one, cannot seem to figure it out. Essentially I have a method that takes in a Func<T>
. I want to be able to define what that func returns and then check if that func has been called in the code. For example:
public class DoIt
{
public bool Execute(Func<int, int, bool> func)
{
return func(1,2);
}
}
...
[TestMethod]
public void TestIt
{
var it = new DoIt();
Func<int, int, bool> funcSpy = Substitute.For<Func<int, int, bool>>();
funcSpy.Returns((d, dd) => true); //When I do this I get a CouldNotSetReturnDueToLastCallException
//or
funcSpy.Invoke(Arg.Any<int>(), Arg.Any<int>()).Returns(true); //When I do this I get RedundantArgumentMatcherException
var actual = it.Execute(funcSpy);
actual.Should().BeTrue();
funcSpy.Received(1).Invoke(Arg.Any<int>(), Arg.Any<int>());
}
Thanks
Related links Found some links that helped with the assertion part and another hinted how do do the func but can't get it to work for my scenario
- https://stackoverflow.com/questions/33017510/mock-result-from-func-with-nsubstitute
- link 2
Version 2 works for me without RedundantArgumentMatcherException and is the right syntax.
Personally I would ask if it is really a good thing to use a mocking framework for this test? Why not just write the test without it?
E.g.:
[TestMethod]
public void TestIt()
{
var it = new DoIt();
int? value1 = null;
int? value2 = null;
var actual = it.Execute((x, y) =>
{
value1 = x;
value2 = y;
return true;
});
actual.Should().BeTrue();
value1.Should().Be(1);
value2.Should().Be(2);
}
Not as fancy as the NSubstitute version but way easier to understand.
Thank you, so the 2nd way is probably what I need to go for, maybe I need an update.
But yeah you make a good point, I can do all that funky mocking manually and at least I have control and know what it is doing. Damn I fell back into the "mock all the things" trap.
Cheers
I think the question has been answered and therefore I will close this one.
Please let us know if you need further information or would like us to take another look at this