FakeItEasy 配置 fake 以在下次调用时抛出异常和 return 值

FakeItEasy configure fake to throw exception and return value on the next call

我们必须实施重试机制。

为了测试 RetryProvider,我想要一个伪造的 class 在前两次调用中抛出异常,但 return 在第三次调用中抛出一个有效对象。

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

我想要类似的东西:

如何配置我的假货来执行此操作?

提前致谢

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

A.CallTo(() => fakeRepo.Get(1))
     .Throws<NullReferenceException>()
     .Once()
     .Then
     .Throws<NullReferenceException>()
     .Once()
     .Then
     .Returns('a');

Specifying different behaviors for successive calls 查看更多相关信息。

这应该有效:

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

另一种方法,如序列:

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);

可以有扩展方法:

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);
}

可以这样称呼它:

A.CallTo(() => this.fakeRepo.Get(1)).ReturnsNextLazilyFromSequence(
    () => throw new Exception(),
    () => throw new Exception(),
    () => "a");