FakeItEasy 配置 fake 以在下次调用时抛出异常并返回值

xer*_*him 4 .net c# unit-testing mocking fakeiteasy

我们必须实施重试机制。

为了测试RetryProvider,我想要一个假的类在前两次调用时抛出异常,但在第三次调用时返回一个有效的对象。

在正常情况下(不抛出异常)我们可以使用 A.CallTo(() => this.fakeRepo.Get(1)).ReturnsNextFromSequence("a", "b", "c");

我想要类似的东西:

  • 第一次调用: throw new Exception();
  • 第二次调用: throw new Exception();
  • 第三次调用:返回“成功”;

我如何配置我的假货来做到这一点?

提前致谢

The*_*ock 6

var fakeRepo = A.Fake<IFakeRepo>();

A.CallTo(() => fakeRepo.Get(1))
     .Throws<NullReferenceException>()
     .Once()
     .Then
     .Throws<NullReferenceException>()
     .Once()
     .Then
     .Returns('a');
Run Code Online (Sandbox Code Playgroud)

指定连续调用的不同行为中查看更多相关信息。


All*_*est 6

这应该有效:

A.CallTo(() => this.fakeRepo.Get(1))
    .Throws<Exception>().Twice()
    .Then
    .Returns("a");
Run Code Online (Sandbox Code Playgroud)

另一种方法是像序列一样:

var funcs = new Queue<Func<string>>(new Func<string>[]
{
    () => throw new Exception(),
    () => throw new Exception(),
    () => "a",
});
A.CallTo(() => this.fakeRepo.Get(1)).ReturnsLazily(() => funcs.Dequeue().Invoke()).NumberOfTimes(queue.Count);
Run Code Online (Sandbox Code Playgroud)

可以有扩展方法:

public static IThenConfiguration<IReturnValueConfiguration<T>> ReturnsNextLazilyFromSequence<T>(
    this IReturnValueConfiguration<T> configuration, params Func<T>[] valueProducers)
{
    if (configuration == null) throw new ArgumentNullException(nameof(configuration));
    if (valueProducers == null) throw new ArgumentNullException(nameof(valueProducers));

    var queue = new Queue<Func<T>>(valueProducers);
    return configuration.ReturnsLazily(x => queue.Dequeue().Invoke()).NumberOfTimes(queue.Count);
}
Run Code Online (Sandbox Code Playgroud)

像这样调用它:

A.CallTo(() => this.fakeRepo.Get(1)).ReturnsNextLazilyFromSequence(
    () => throw new Exception(),
    () => throw new Exception(),
    () => "a");
Run Code Online (Sandbox Code Playgroud)

  • 或`抛出&lt;Exception&gt;().Twice().Then.Returns("a")`;) (2认同)