I have a method which is invoked multiple times within a foreach
loop, each time with the same parameter values.
foreach (var item in myCollection)
{
// do some stuff with item
// then...
var result = _myService.Foo(aConstant, anotherConstant);
// do something with result
}
I am trying to write a test that ensures the loop continues iterating even if _myService.Foo()
throws an exception on the first time through.
In Moq, I am allowed to chain together calls to Returns
and Throws
like so:
mockService.Setup(x => x.Foo(aConstant, anotherConstant)).Throws<Exception>().Returns(someResult);
This will cause the call to Foo
to throw an Exception but all subsequent calls will return someResult
. My main goal is to ensure that a try/catch block is wrapped around the second half of code inside my foreach block so that the loop continues even if an Exception occurs.
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
}
}
How can I accomplish something similar to this in FakeItEasy? Or is there a different (better) strategy I could use for doing this kind of assertion?
You can now chain configurations using 'Then'. You can read more about it in the FakeItEasy documentation for changing behavior between calls.
This is an example:
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));
}
In case it helps anyone else…
I figured out a way to do this for methods with void
return type. I used the Invokes()
method:
A.CallTo(() => _fakeService.VoidMethod(aConstant, anotherConstant))
.Invokes(ThrowExceptionOnFirstInvocation);
Then outside the Test method, I defined the ThrowExceptionOnFirstInvocation
function:
private void ThrowExceptionOnFirstInvocation(IFakeObjectCall obj)
{
if (_numInvocations++ == 0) throw new Exception();
}
private int _numInvocations;
I am still not sure how to do this for a method which returns something though.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With