【发布时间】:2019-04-01 07:57:51
【问题描述】:
我需要模拟一个接口来调用 MSMQ,有没有办法可以使用 Moq 来模拟真正的 MSMQ 场景,队列中有 10 条消息,我调用模拟函数 10 次,我可以得到一个预定义的对象,第 11 次我应该得到一个不同的返回值(例如 null)?
【问题讨论】:
我需要模拟一个接口来调用 MSMQ,有没有办法可以使用 Moq 来模拟真正的 MSMQ 场景,队列中有 10 条消息,我调用模拟函数 10 次,我可以得到一个预定义的对象,第 11 次我应该得到一个不同的返回值(例如 null)?
【问题讨论】:
Moq 现在在 Moq 命名空间中有一个名为 SetupSequence() 的扩展方法,这意味着您可以为每个特定调用定义不同的返回值。
一般的想法是,您只需链接所需的返回值。 在下面的示例中,第一个调用将返回 Joe,第二个调用将返回 Jane:
customerService
.SetupSequence(s => s.GetCustomerName(It.IsAny<int>()))
.Returns("Joe") //first call
.Returns("Jane"); //second call
更多信息here。
【讨论】:
我有时会在这种情况下使用一个简单的计数器:
int callCounter = 0;
var mock = new Mock<IWhatever>();
mock.Setup(a => a.SomeMethod())
.Returns(() =>
{
if (callCounter++ < 10)
{
// do something
}
else
{
// do something else
}
});
【讨论】:
.CallBack( ... ),其中省略号表示修改callCounter 和可能的其他状态的委托。
您也可以设置一个单独的函数来执行此操作。如果你愿意,你甚至可以给函数传递一个参数:
_serviceMock.Setup(x => x.SomeMethod(It.IsAny<String>())).Returns((String param) => getTimesCalled(param));
【讨论】: