2011-08-12 209 views

回答

39

我會利用Callback,並增加一個計數器,以確定是否要由Callback拋出異常。

[Test] 
public void TestMe() 
{ 
    var count = 0; 
    var mock = new Mock<IMyClass>(); 
    mock.Setup(a => a.MyMethod()).Callback(() => 
     { 
      count++; 
      if(count == 1) 
       throw new ApplicationException(); 
     }); 
    Assert.Throws(typeof(ApplicationException),() => mock.Object.MyMethod()); 
    Assert.DoesNotThrow(() => mock.Object.MyMethod()); 
} 

public interface IMyClass 
{ 
    void MyMethod(); 
} 
+0

這是一個很好的答案,一旦你想要發生兩件事情,這種方法就變得可取了。 – anthony

+0

這種方法很簡單,但很好,但請從@Mathias的答案中查看Phil Haack的帖子。這很漂亮。如果你想返回一個值序列,但使用擴展方法你可以做一些像'reader.Setup(r => r.Read())。ReturnsInOrder(true,true,false);' – rsbarro

+3

ReturnsInOrder如何使用它作爲序列的一部分拋出異常並不明顯。 – anthony

16

,我已經拿出了迄今爲止最好的是這樣的:

interface IFoo 
{ 
    void Bar(); 
} 

[Test] 
public void TestBarExceptionThenSuccess() 
{ 
    var repository = new MockRepository(MockBehavior.Default); 
    var mock = repository.Create<IFoo>(); 

    mock.Setup(m => m.Bar()). 
     Callback(() => mock.Setup(m => m.Bar())). // Setup() replaces the initial one 
     Throws<Exception>();      // throw an exception the first time 

    ... 
} 
+1

+1這是一個很酷的方法。對於那些陷入代碼的人來說,可能並不清楚。 – rsbarro

+3

輝煌。這對我很好。 –

+0

不錯的一個,我沒有想到這個! –

5

菲爾哈克對設立返回結果的特定序列的方法,一個有趣的blog post。看起來,這將是一個很好的起點,涉及一些工作,因爲不是某種類型的值的序列,而是需要現在有一個可能是T類型或異常的結果序列。

+0

有趣的閱讀,謝謝。 – anthony

3

從Moq 4.2開始,您可以使用內置方法SetupSequence()(如@RichardBarnett評論所述)。

實施例:

var mock = new Mock<IMyClass>(); 
mock.SetupSequence(x => x.MyMethod("param1")) 
    .Throws<MyException>() 
    .Returns("test return"); 
相關問題