In the following example I have a simple Service class which does something with it's input and a Processor which calls the Service.DoService() twice, passing the same InputParameters object, first x = 5, then x = 100; The problem is that in the unit tests I want to check if the DoService() method was called once with the original values (x==5) and once with the new values (x==100), but apparently it is called twice with x==100
public class InputParameters
{
public int x, y;
}
public interface IService
{
bool DoSomething(InputParameters input);
}
public class Service : IService
{
public bool DoSomething(InputParameters input)
{
return input.x > input.y;
}
}
public class Processor
{
public IService _service;
public Processor(IService theServive)
{
_service = theServive;
}
public void Process()
{
InputParameters input = new InputParameters();
input.x = 5;
input.y = 50;
_service.DoSomething(input);
input.x = 100;
_service.DoSomething(input);
}
and the test
private Mock<IService> _serviceMock;
private Processor _processor;
[SetUp]
public void Setup()
{
_serviceMock = new Mock<IService>();
_processor = new Processor(_serviceMock.Object);
}
[Test]
public void Test()
{
_serviceMock.Setup(service => service.DoSomething(
It.IsAny<InputParameters>()
)).Returns(() => false);
_processor.Process();
_serviceMock.Verify(service => service.DoSomething(
It.Is<InputParameters>(input => input.x == 5)
), Times.Exactly(1)); //returns 0 times called
_serviceMock.Verify(service => service.DoSomething(
It.Is<InputParameters>(input => input.x == 100)
), Times.Exactly(1)); //return 2 times calledd
I've debugged the execution and I can see that the first invocations arguments are changed when I call input.x = 100, and I do not understand how Moq keeps just a reference to the invocation arguments?
I've tried also a different setup, same result:
_serviceMock.Setup(service => service.DoSomething(
It.Is<InputParameters>(input => input.x == 5)
)).Returns(() => true);
_serviceMock.Setup(service => service.DoSomething(
It.Is<InputParameters>(input => input.x == 100)
)).Returns(() => false);
Code can be found here: https://github.com/rufusz/MoqInvocationCountIssue