0
我想要一个第一次返回的模拟,然后1
在此后调用该方法的任何时候返回。问题是如果方法被调用4次,我必须写:
mock.SetupSequence(x => x.GetNumber())
.Returns(0)
.Returns(1)
.Returns(1)
.Returns(1);
否则,该方法返回 null。
有什么办法可以写,在初始调用之后,方法返回1
?
0
我想要一个第一次返回的模拟,然后1
在此后调用该方法的任何时候返回。问题是如果方法被调用4次,我必须写:
mock.SetupSequence(x => x.GetNumber())
.Returns(0)
.Returns(1)
.Returns(1)
.Returns(1);
否则,该方法返回 null。
有什么办法可以写,在初始调用之后,方法返回1
?
最干净的方法是创建一个Queue
并将.Dequeue
方法传递给Returns
.Returns(new Queue<int>(new[] { 0, 1, 1, 1 }).Dequeue);
这不是特别花哨,但我认为它会起作用:
var firstTime = true;
mock.Setup(x => x.GetNumber())
.Returns(()=>
{
if(!firstTime)
return 1;
firstTime = false;
return 0;
});
派对有点晚了,但如果你还想使用 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.1和Moq@4.14.1测试了所有内容- 通过 ✔</p>
只需设置一个扩展方法,例如:
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);
您可以使用临时变量来跟踪调用该方法的次数。
例子:
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);
}
}