我是Moq的新手,无法确定我如何订购设置。我有以下代码:
_orderRepository.Setup(r => r.Update(It.Is<Order>(a => ((int)a.OrderStatusReference.EntityKey.EntityKeyValues[0].Value) == 2)))
.Throws(exception)
.AtMost(5);
我想要执行5次(如果更新失败,则重试逻辑)。在第5次之后我想设置并期望它成功(不抛出异常):
_orderRepository.Setup(r => r.Update(It.Is<Order>(a => ((int)a.OrderStatusReference.EntityKey.EntityKeyValues[0].Value) == 2))).AtMostOnce();
令人遗憾的是,它继续使用第一个代码示例,但从未成功更新。
如果我没有使用Throws方法,那么我可以使用Callback方法,但抛出后它不可用:(。
如果有办法或者这是Moq的限制吗?
答案 0 :(得分:16)
Bah ......有办法!
您可以使用队列返回返回值列表(策略在此处解释得很清楚:http://haacked.com/archive/2009/09/29/moq-sequences.aspx)。
以下是该博客的示例:
如果你想要这个(它没有):
reader.Setup(r => r.Read()).Returns(true);
reader.Setup(r => r.Read()).Returns(true);
reader.Setup(r => r.Read()).Returns(false);
请改为:
Queue listOfOperations = new Queue<bool>(new bool[] { true, true, false });
reader.Setup(r => r.Read())
.Returns(() => listOfOperations.Dequeue());
每次调用Read()时,都会使用Queue中的新值。
享受!
答案 1 :(得分:2)
我也需要同样的东西,最后写了这个扩展方法,这对我有用:
public static class MoqExtensions {
public static void Returns<TMock,TResult>(this ISetup<TMock, TResult> source, params TResult[] results) where TMock : class {
int currentResultIndex = 0;
source.Returns (() => {
if(currentResultIndex >= results.Length) {
currentResultIndex = 0;
}
return results [currentResultIndex++];
});
}
}
样本用法是:
someMock.Setup(o => o.AMethodWithReturnTypeInt()).Returns(1, 2, 3, 4);
对于此示例,如果您调用stubbed方法-let的说 - 6次,它将分别返回1,2,3,4,1,2。
希望这会有所帮助......
答案 2 :(得分:1)
Moq不支持预期的排序。有关详细信息,请参阅here。
虽然我目前使用Moq,但之前我曾经使用过RhinoMocks,它肯定有一些我偶尔会错过Moq的功能 - 订购的期望就是其中之一。