如何使模拟首次抛出异常并返回第二个值

Ser*_*ero 7 c# unit-testing moq

我使用Moq作为我的模拟框架,我需要测试一个类,当运行特定类型的异常时,它将继续尝试,直到执行完成后情况得到解决.

所以我需要的是类似的东西:

myMock = Mock<IFoo>();

myMock.Setup(m => m.Excecute()).Throws<SpecificException>();
myMock.Setup(m => m.Execute());

var classUnderTest = MyClass(myMock);
classUnderTest.DoSomething();

Assert.AreEqual(expected, classUnderTest.Result);
Run Code Online (Sandbox Code Playgroud)

谢谢你提供的所有帮助.

Tru*_*ill 15

这是一种方法,基于每次调用返回不同值的Moq QuickStart示例.

var mock = new Mock<IFoo>();
var calls = 0;
mock.Setup(foo => foo.GetCountThing())
    .Returns(() => calls)
    .Callback(() =>
     {
        calls++;
        if (calls == 1)
        {
            throw new InvalidOperationException("foo");
        }
     });

try
{
    Console.WriteLine(mock.Object.GetCountThing());
}
catch (InvalidOperationException)
{
    Console.WriteLine("Got exception");
}

Console.WriteLine(mock.Object.GetCountThing());
Run Code Online (Sandbox Code Playgroud)

如果方法返回void,请使用:

var myMock = new Mock<IFoo>();
bool firstTimeExecuteCalled = true;

myMock.Setup(m => m.Execute())
      .Callback(() =>
       {
            if (firstTimeExecuteCalled)
            {
                firstTimeExecuteCalled = false;
                throw new SpecificException();
            }
       });

try
{
    myMock.Object.Execute();
}
catch (SpecificException)
{
    // Would really want to call Assert.Throws instead of try..catch.
    Console.WriteLine("Got exception");
}

myMock.Object.Execute();
Console.WriteLine("OK!");
Run Code Online (Sandbox Code Playgroud)