2011-10-27 91 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

相關問題