在FakeItEasy伪造一名调查员

hca*_*ber 3 tdd unit-testing mocking fakeiteasy

如何使用FakeItEasy创建假冒,允许在连续调用时使用不同的返回值.这是我希望能够做到的一个例子:

var enumerator = A.Fake<IDictionaryEnumerator>();
A.CallTo(() => enumerator.MoveNext()).Returns(true);  //Expected value for first call
A.CallTo(() => enumerator.Key).Returns("key1");
A.CallTo(() => enumerator.Value).Returns("value1");
A.CallTo(() => enumerator.MoveNext()).Returns(false); //Expected value for second call

Assert.IsTrue(enumerator.MoveNext());    //Fails
Assert.IsFalse(enumerator.MoveNext());   
Run Code Online (Sandbox Code Playgroud)

断言将失败,因为它最后一次设置的MoveNext将覆盖第一个.

可以在FakeItEasy中做我想做的吗?

.

[编辑]
澄清原始问题的例子并在下面提供了一个工作示例.

根据Patrik的答案,此代码显示了如何设置假货.诀窍是反转所有设置和使用Once().

var enumerator = A.Fake<IDictionaryEnumerator>();
A.CallTo(() => enumerator.MoveNext()).Returns(false).Once();
A.CallTo(() => enumerator.MoveNext()).Returns(true).NumberOfTimes(2);
A.CallTo(() => enumerator.Key).Returns("key2").Once();
A.CallTo(() => enumerator.Value).Returns("value2").Once();
A.CallTo(() => enumerator.Key).Returns("key1").Once();
A.CallTo(() => enumerator.Value).Returns("value1").Once();

while(enumerator.MoveNext())
{
    Debug.WriteLine(enumerator.Key + ": "+ enumerator.Value);               
}
Run Code Online (Sandbox Code Playgroud)

这将打印:

key1: value1
key2: value2
Run Code Online (Sandbox Code Playgroud)

Pat*_*gne 6

我不完全确定我理解你的意思,你提供的代码总是会失败.但是,如果你的意思是你希望它在第二次被调用时返回true,那么就可以完成它.我能想到几种不同的方式,其中两种是:

A.CallTo(() => enumerator.MoveNext()).ReturnsNextFromSequence(false, true);
Run Code Online (Sandbox Code Playgroud)

另一种方式是:

A.CallTo(() => enumerator.MoveNext()).Returns(true);
A.CallTo(() => enumerator.MoveNext()).Returns(false).Once();
Run Code Online (Sandbox Code Playgroud)

编辑:

第二,虽然我想我更了解你的问题,你想要发生的是MoveNext第一次应该返回true而第二次是false吗?如果是这种情况,只需更改上面示例中的值的顺序.

FakeItEasy不使用记录/重放模型,并且您的正确性是最新配置的规则优先于任何先前指定的规则.这就是为什么你必须指定repeat - ".Once()" - 在最新配置上它只有一次有效.

最新优先级有很多原因,其中最重要的一个原因是它允许您在夹具设置中设置默认返回值并覆盖它以在某些测试中返回特定值,这在以下情况下是不可能的.使用记录/重播模型.