如何让FakeItEasy伪造对象的方法抛出第一次调用并返回第二次?

Jes*_*ebb 4 c# exception moq mocking fakeiteasy

我有一个在foreach循环中多次调用的方法,每次都有相同的参数值.

foreach (var item in myCollection)
{
    // do some stuff with item
    // then...
    var result = _myService.Foo(aConstant, anotherConstant);
    // do something with result
}
Run Code Online (Sandbox Code Playgroud)

我正在尝试编写一个测试,确保循环继续迭代,即使_myService.Foo()第一次抛出异常.

Moq中,我被允许将调用链接在一起Returns并且Throws如此:

mockService.Setup(x => x.Foo(aConstant, anotherConstant)).Throws<Exception>().Returns(someResult);
Run Code Online (Sandbox Code Playgroud)

这将导致调用Foo抛出异常,但所有后续调用都将返回someResult.我的主要目标是确保try/catch块包含在foreach块内的代码的后半部分,以便即使发生异常,循环也会继续.

foreach (var item in myCollection)
{
    // do some stuff with item
    // then...
    try
    {
        var result = _myService.Foo(aConstant, anotherConstant);
        // do something with result
    }
    catch (Exception e)
    {
        // ignore any exceptions here and continue looping
    }
}
Run Code Online (Sandbox Code Playgroud)

如何才能在FakeItEasy中完成与此类似的操作?或者我可以使用不同的(更好的)策略来做这种断言吗?

Bla*_*rad 10

您现在可以使用"Then"链接配置.您可以在FakeItEasy文档中阅读有关它的更多信息,以更改调用之间的行为.

这是一个例子:

public interface IFoo
{
    int Do();
}

[Test]
public void ThrowsFirstTime()
{
    var fakeFoo = A.Fake<IFoo>();
    A.CallTo(() => fakeFoo.Do()).Throws<Exception>().Once().Then.Returns(1);

    Assert.Throws<Exception>(()=>fakeFoo.Do());
    int t = fakeFoo.Do();

    A.CallTo(() => fakeFoo.Do()).MustHaveHappened(Repeated.Exactly.Twice);
    Assert.That(t, Is.EqualTo(1));
}
Run Code Online (Sandbox Code Playgroud)