Reputation: 500
I am trying to set up Moq to throw an exception on the first invocation and then return void on the second invocation. The method I'm mocking has a void
return type (e.g. public void Bar()
).
Things I have tried
This has compile errors because Returns
requires an argument and SetupSequence
requires type arguments.
_mock.SetupSequence(m => m.Bar())
.Throws<Exception>()
.Returns();
This has a compile error because Void
is not a type in C#.
_mock.SetupSequence<IMyMock, Void>(m => m.Bar())
.Throws<Exception>() // first invocation throws exception
.CallBase();
Workaround
In the end I gave up on SetupSequence()
and switched to Callback()
to throw an exception.
var firstTime = true;
_mock.Setup(m => m.Bar())
.Callback(() =>
{
if (firstTime)
{
firstTime = false;
throw new Exception();
}
});
Question
SetupSequence
takes a Func
, not an Action
. Am I correct in assuming that this means SetupSequence()
cannot be used to mock void methods?
Upvotes: 3
Views: 3726
Reputation: 84735
You can do this starting with Moq 4.8.0:
SetupSequence
support for void
methods was discussed in GitHub issue #451
and added with GitHub pull request #463
.
You're probably looking for the new .Pass()
method:
mock.SetupSequence(m => m.VoidMethod())
.Throws(new InvalidOperationException())
.Pass()
.Pass()
.Throws(new InvalidOperationException())
.Pass();
Note that trailing calls to .Pass()
are probably unnecessary.
Upvotes: 11