Moq - 订购设置(期望)

时间:2009-09-22 08:20:53

标签: .net unit-testing moq

我是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的限制吗?

3 个答案:

答案 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的功能 - 订购的期望就是其中之一。