C# 最小起订量中的设置序列

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11308328/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 17:20:10  来源:igfitidea点击:

SetupSequence in Moq

c#unit-testingmockingmoq

提问by Florian

I want a mock returns a 0 the first time, then returns 1 anytime the method was called. The problem is that if the method is called 4 times, I should write that :

我希望模拟第一次返回 0,然后在调用该方法时返回 1。问题是,如果该方法被调用 4 次,我应该这样写:

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

otherwise the method returns null.

否则该方法返回 null。

Is there any way to write that the next times the method was called after the first time, the method returns 1 ? Thank you

有什么办法可以写出在第一次之后调用该方法的下一次,该方法返回 1 吗?谢谢

Is it good to have more "operators" for SetupSequence ? If you think YES you can vote : http://moq.uservoice.com/forums/11304-general/suggestions/2973521-setupsequence-more-operators

为 SetupSequence 设置更多的“操作符”好不好?如果您认为是,您可以投票:http: //moq.uservoice.com/forums/11304-general/suggestions/2973521-setupsequence-more-operators

采纳答案by Romain Verdier

That's not particulary fancy, but I think it would work:

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

    var firstTime = true;

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

                            firstTime = false;
                            return 0;
                        });

回答by sloth

You can use a temporary variable to keep track of how many times the method was called.

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

Example:

例子:

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);
    }
}

回答by Jakub Konecki

The cleanest way is to create a Queueand pass .Dequeuemethod to Returns

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

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

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

回答by Thomas Heijtink

Just setup an extension method like:

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

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

And then setup the return like:

然后设置返回,如:

var queue = new Queue<int>(new []{0, 1, 1, 1});
mock.Setup(m => m.GetNumber).Returns(queue.Denqueue);

回答by Connor Low

Bit late to the party, but if you want to still use Moq's API, you could call the Setupfunction in the action on the final Returnscall:

聚会有点晚了,但如果您仍想使用 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...

I wanted to demonstrate using StepSequence, but for the OP's specific case, you could simplify and have everything in a Setupmethod:

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

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

Tested everything here with [email protected]and [email protected]- passes ?

[email protected][email protected]在这里测试了所有东西- 通过了吗?