81

0我想要一个第一次返回的模拟,然后1在此后调用该方法的任何时候返回。问题是如果方法被调用4次,我必须写:

mock.SetupSequence(x => x.GetNumber())
    .Returns(0)
    .Returns(1)
    .Returns(1)
    .Returns(1);

否则,该方法返回 null。

有什么办法可以写,在初始调用之后,方法返回1

4

5 回答 5

67

最干净的方法是创建一个Queue并将.Dequeue方法传递给Returns

.Returns(new Queue<int>(new[] { 0, 1, 1, 1 }).Dequeue);

于 2012-07-03T10:02:33.137 回答
54

这不是特别花哨,但我认为它会起作用:

    var firstTime = true;

    mock.Setup(x => x.GetNumber())
        .Returns(()=>
                        {
                            if(!firstTime)
                                return 1;

                            firstTime = false;
                            return 0;
                        });
于 2012-07-03T09:59:26.633 回答
15

派对有点晚了,但如果你还想使用 Moq 的 API,你可以Setup在最终调用的操作中调用该函数Returns

var mock = new Mock<IFoo>();
mock.SetupSequence(m => m.GetNumber())
    .Returns(4)
    .Returns(() =>
    {
        // Subsequent Setup or SetupSequence calls "overwrite" their predecessors: 
        // you'll get 1 from here on out.
        mock.Setup(m => m.GetNumber()).Returns(1);
        return 1;
    });

var o = mock.Object;
Assert.Equal(4, o.GetNumber());
Assert.Equal(1, o.GetNumber());
Assert.Equal(1, o.GetNumber());
// etc...

我想演示 using StepSequence,但对于 OP 的特定情况,您可以简化并在一个Setup方法中包含所有内容:

mock.Setup(m => m.GetNumber())
    .Returns(() =>
    {
        mock.Setup(m => m.GetNumber()).Returns(1);
        return 4;
    });

在这里使用xunit@2.4.1Moq@4.14.1测试了所有内容- 通过 ✔</p>

于 2020-05-08T19:16:24.220 回答
5

只需设置一个扩展方法,例如:

public static T Denqueue<T>(this Queue<T> queue)
{
    var item = queue.Dequeue();
    queue.Enqueue(item);
    return item;
}

然后像这样设置回报:

var queue = new Queue<int>(new []{0, 1, 1, 1});
mock.Setup(m => m.GetNumber).Returns(queue.Denqueue);
于 2017-02-23T07:44:33.880 回答
4

您可以使用临时变量来跟踪调用该方法的次数。

例子:

public interface ITest
{ Int32 GetNumber(); }

static class Program
{
    static void Main()
    {
        var a = new Mock<ITest>();

        var f = 0;
        a.Setup(x => x.GetNumber()).Returns(() => f++ == 0 ? 0 : 1);

        Debug.Assert(a.Object.GetNumber() == 0);
        for (var i = 0; i<100; i++)
            Debug.Assert(a.Object.GetNumber() == 1);
    }
}
于 2012-07-03T09:59:47.967 回答