我有一个在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中,我可以将调用链接到Returns
和Throws
,如下所示:
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中完成类似的内容?或者,我可以使用不同的(更好的)策略来做这种断言吗?
答案 0 :(得分:9)
您现在可以使用“然后”链接配置。您可以在changing behavior between calls的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));
}
答案 1 :(得分:1)
如果它可以帮助其他人......
我找到了一种为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;
我仍然不确定如何为返回某些东西的方法执行此操作。