Let's say we have this method:
string Add(int a, int b) {
var sum = _calculator.Add(a,b);
var response = _formatter.Format(sum);
return response;
}
Now I want to unit-test this method. Assume of course the code is not actually that trivial, _calculator and _formatter might be external services, there's some logic in the method itself, and I want to make sure I'm calling all of my dependencies correctly and return the correct result. Of course _calculator and _formatter will be mocked, but what should I mock and what should I verify? I see too options -
Setup the mocks to respond to any input with specific output and later make sure they were called with the expected input:
calculator = Substitute.For<ICalculator>();
calculator.Add(Arg.Any<int>(), Arg.Any<int>()).returns(123);
formatter = Substitute.For<IFormatter>();
formatter.Format(Arg.Any<int>()).returns("yup");
var subject = new DidntThinkOfClassName(calculator, formatter);
var res = subject.Add(1, 2);
calculator.Received(1).Add(1, 2);
formatter.Received(1).Format(123);
res.ShouldBe("yup");
Or setup the mocks to ONLY respond to the expected input, and then only verify the end result:
calculator = Substitute.For<ICalculator>();
calculator.Add(1, 2).returns(123);
formatter = Substitute.For<IFormatter>();
formatter.Format(123).returns("yup");
var subject = new DidntThinkOfClassName(calculator, formatter);
var res = subject.Add(1, 2);
res.ShouldBe("yup");
In the first option I'm accepting any input, which means simpler mocks, but I then have to verify the received calls. In the second option I arrange my mocks in such a way that the end result can only be achieved if each and every mock received exactly what it was configured to receive, so I only need to check the end result.
What would you say is better? Is there a better solution i'm missing?