Reputation: 1039
I have the following classes structure:
public class MyObj
{
public int Number;
}
public interface IService
{
int ProcessInt(MyObj obj);
}
public class Service : IService
{
public int ProcessInt(MyObj myObj)
{
return myObj.Number;
}
}
and then the consumer class
public class Class1
{
public void Run(IService s)
{
var obj = new MyObj {Number = 1};
Console.WriteLine(s.ProcessInt(obj));
}
}
and then the unit test
[TestFixture]
public class MyTest
{
private readonly Mock<IService> _service = new Mock<IService>(MockBehavior.Strict);
private readonly Class1 _sut = new Class1();
[SetUp]
public void SetUp()
{
var obj = new MyObj {Number = 1};
_service.Setup(x => x.ProcessInt(obj)).Returns(1);
}
[Test]
public void TestClass1()
{
_sut.Run(_service.Object);
}
}
The problem I have is that when I run the unit test, I get "Moq.MockException : IService.ProcessInt(MoqStuff.MyObj) invocation failed with mock behavior Strict.All invocations on the mock must have a corresponding setup." which is weird since I have the setup for that input.
Is this an expected behavior of Moq framework? Is there any way I can fix that?
Thank you
Upvotes: 0
Views: 2822
Reputation: 24901
You have this code in your SetUp
method:
var obj = new MyObj {Number = 1};
_service.Setup(x => x.ProcessInt(obj)).Returns(1);
Here you set up expectation, that ProcessInt
is called with this specific object obj
.
However, in your method Run
you create another object:
var obj = new MyObj {Number = 1};
Though property value is the same, this object is totally different from the one you created in your SetUp
method. This is the reason why you get exception about missing setup.
What you can do instead is set up your service for any input parameter using It.IsAny
:
[SetUp]
public void SetUp()
{
_service.Setup(x => x.ProcessInt(It.IsAny<MyObj>())).Returns(1);
}
This setup will work for any parameter value.
Or if you want to match only based on some criteria, you can use It.Is
:
[SetUp]
public void SetUp()
{
// setup only for cases where obj.Number == 1
_service
.Setup(x => x.ProcessInt(It.Is<MyObj>(o => o.Number == 1 )))
.Returns(1);
// setup only for cases where obj.Number == 2
_service
.Setup(x => x.ProcessInt(It.Is<MyObj>(o => o.Number == 2 )))
.Returns(2);
}
Upvotes: 5