我可以使用Moq的SetupSequence引发异常然后返回void吗?

gir*_*uru 2 c# moq mocking

我试图将Moq设置为在第一次调用时引发异常,然后在第二次调用时返回void。我嘲笑的方法具有void返回类型(例如public void Bar())。

我尝试过的事情

由于Returns需要参数和SetupSequence类型参数,因此存在编译错误。

_mock.SetupSequence(m => m.Bar())
    .Throws<Exception>()
    .Returns();
Run Code Online (Sandbox Code Playgroud)

由于Void不是C#中的类型,因此存在编译错误。

_mock.SetupSequence<IMyMock, Void>(m => m.Bar())
    .Throws<Exception>() // first invocation throws exception
    .CallBase();
Run Code Online (Sandbox Code Playgroud)

解决方法

最后,我放弃了SetupSequence(),转而Callback()抛出异常。

var firstTime = true;
_mock.Setup(m => m.Bar())
    .Callback(() =>
    {
        if (firstTime)
        {
            firstTime = false;
            throw new Exception();
        }
    });
Run Code Online (Sandbox Code Playgroud)

SetupSequence需要一个Func,而不是一个Action。我是否SetupSequence()可以假设此方法不能用于模拟void方法,对吗?

sta*_*ica 7

您可以从Moq 4.8.0开始执行此操作:

SetupSequencevoidGitHub问题中讨论了对方法的支持,并在#451GitHub pull request中添加了对方法的支持#463

您可能正在寻找新.Pass()方法:

mock.SetupSequence(m => m.VoidMethod())
    .Throws(new InvalidOperationException())
    .Pass()
    .Pass()
    .Throws(new InvalidOperationException())
    .Pass();
Run Code Online (Sandbox Code Playgroud)

请注意,.Pass()可能不需要尾随调用。