我正在寻找一个关于moq's Setup
方法在设置一个模拟对象时的确切解释,该模拟对象将从“被测系统”中多次调用(sut)
例如:
如果我有一个模拟对象设置并调用我的Sut方法。
var inputParamObject = new inputParamObject();
this.mock.Setup(x => x.MethodCall(inputParam).Returns(this.mock.Object);
Sut.WithCallLoopingMethodThatCallsTheMockObject();
现在,我正在处理的真正代码是遗留的,而且很难在这里显示,所以不幸的是,这是我认为正在发生的事情的简单表示。
问题,我看到的是如果inputParamObject
用于循环的第一次迭代,它会重新启动正确的模拟对象。但是,在第二次迭代中,它返回null。
如果我将上面的代码更改为使用第二个InputParamObject,它将再次返回模拟并且我的测试将通过:
var inputParam = new InputParam();
var inputParam2 = new InputParam();
this.mock.Setup(x => x.MethodCall(inputParam).Returns(this.mock.Object);
this.mock.Setup(x => x.MethodCall(inputParam2).Returns(this.mock.Object);
Sut.WithCallLoopingMethodThatCallsTheMockObject();
我认为模拟的第二个设置只会覆盖第一个,但似乎并非如此。我也知道我可以这样设置,测试将通过。
this.mock.Setup(x => x.MethodCall(It.IsAny<InputParamObject>).Returns(this.mock.Object);
我很抱歉这是一个人为的例子,也许需要更多的细节来理解,但
当我有一个安装调用时,有人能告诉我究竟发生了什么,而在这个例子中有两个吗?
此指针的特定参考资料的指针也很棒。
由于
答案 0 :(得分:0)
我从未遇到过多次调用模拟对象的方法的任何问题。我认为您的测试失败可能还有其他几个原因。
您似乎每个测试夹具都有一个模拟对象实例。其他测试可能会对模拟对象设置产生副作用。尝试在每个测试中创建自己的实例。您可能会发现有用的单元测试上下文模式 http://java.dzone.com/articles/introducing-unit-testing
您的方法WithCallLoopingMethodThatCallsTheMockObject可能会将inputParamObject的不同实例发送到MethodCall。也许你必须覆盖inputParamObject的Equals方法。
我成功运行的代码如下。
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
const int SERVICE_ID = 123;
ParamObject callParam = new ParamObject(42);
var fakeService = new Mock<IService>();
fakeService.Setup(call => call.MethodCall(callParam)).Returns(fakeService.Object);
fakeService.Setup(call => call.Id).Returns(SERVICE_ID);
Processor sut = new Processor(fakeService.Object, callParam);
// --- Act
sut.WithCallLoopingMethodThatCallsTheMockObject();
}
}
public interface IService
{
int Id { get; }
IService MethodCall(ParamObject param);
}
public class ParamObject
{
private int _id = 0;
public ParamObject(int id)
{
_id = id;
}
}
public class Processor
{
private IService _service;
private ParamObject _serviceCallParam;
public Processor(IService service, ParamObject serviceCallParam)
{
_service = service;
_serviceCallParam = serviceCallParam;
}
public void WithCallLoopingMethodThatCallsTheMockObject()
{
for(int i=0; i<20; i++)
{
IService srv = _service.MethodCall(_serviceCallParam);
Console.WriteLine(String.Format("Iteration {0:00}, service instance id={1}", i, srv.Id));
}
}
}