Reputation: 4645
We have to implement a retry-mechanism.
To test the RetryProvider
, I want a fake of a class to throw exceptions on the first two calls, but return a valid object on the third call.
Under normal circumstances (without throwing exceptions) we could use A.CallTo(() => this.fakeRepo.Get(1)).ReturnsNextFromSequence("a", "b", "c");
I want something similar:
How can I configure my fake to do this?
Thanks in advance
Upvotes: 8
Views: 5125
Reputation: 4492
This should work:
A.CallTo(() => this.fakeRepo.Get(1))
.Throws<Exception>().Twice()
.Then
.Returns("a");
Another way do it like the sequence:
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);
Could have extension method:
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);
}
An call it like this:
A.CallTo(() => this.fakeRepo.Get(1)).ReturnsNextLazilyFromSequence(
() => throw new Exception(),
() => throw new Exception(),
() => "a");
Upvotes: 7
Reputation: 1541
var fakeRepo = A.Fake<IFakeRepo>();
A.CallTo(() => fakeRepo.Get(1))
.Throws<NullReferenceException>()
.Once()
.Then
.Throws<NullReferenceException>()
.Once()
.Then
.Returns('a');
See more about this at Specifying different behaviors for successive calls.
Upvotes: 11