2011-10-27 57 views
7

我正在使用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); 

感谢所有帮助你可以给。

回答

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()); 

如果该方法返回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!"); 
+0

这看起来很有趣,但是,如果该方法是无效的,并且在安装后没有得到“返回”方法呢?实际上,如果“GetCountThing”返回一个int,它就会工作,如果它返回其他东西,它将不会编译。 –

+0

@SergioRomero - 请参阅编辑答案。 – TrueWill

+0

至于如果它不是一个int,请改变你从'Returns'行返回的内容。它不一定是'calls'的价值。 – TrueWill

1

为什么不实际编写你自己的测试对象,这是否?如果它只是用于测试,例如:

public class Mock : IFoo 
{ 
    private int _calls; 

    public Mock() 
    { 
     _calls = 0; 
    } 

    public int Execute() 
    { 
     _calls++; 

     if (_calls == 1) 
      throw new Exception(); 

     return value; 

    } 

} 
+1

在这种情况下,我可以看到这一点。虽然这是一个边缘案例;大多数情况下,我要么需要一个将返回已知常量值的存根或者将验证给定方法被调用的模拟。 Moq可以很容易地创建这两个动态。另外,如果您有一个拥有30个成员的传统接口,并且只需要其中一个用于此测试,则Moq解决方案要短得多。 – TrueWill

相关问题