4

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

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

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

Moq中,我可以将调用链接在一起ReturnsThrows如下所示:

mockService.Setup(x => x.Foo(aConstant, anotherConstant)).Throws<Exception>().Returns(someResult);

这将导致调用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
    }
}

我怎样才能在FakeItEasy中完成与此类似的事情?或者我可以使用不同的(更好的)策略来进行这种断言吗?

4

2 回答 2

11

您现在可以使用“然后”链接配置。您可以在 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));
}
于 2013-11-01T18:00:57.660 回答
1

以防它帮助其他人......</p>

我想出了一种方法来为具有void返回类型的方法执行此操作。我使用的Invokes()方法:

A.CallTo(() => _fakeService.VoidMethod(aConstant, anotherConstant))
                           .Invokes(ThrowExceptionOnFirstInvocation);

然后在 Test 方法之外,我定义了ThrowExceptionOnFirstInvocation函数:

private void ThrowExceptionOnFirstInvocation(IFakeObjectCall obj)
{
    if (_numInvocations++ == 0) throw new Exception();
}

private int _numInvocations;

我仍然不确定如何为返回某些内容的方法执行此操作。

于 2013-11-01T17:12:59.800 回答