2009-06-12 30 views
6

我嘲諷的包裝到MSMQ拋出的異常。包裝只是允許創建一個對象實例,直接調用MessageQueue類的靜態方法。我可以得到一系列好成績,從起訂量

我想測試讀取隊列枯竭。要做到這一點,我希望模擬包裝返回一些好的結果,並在第四次調用時拋出異常,以相同的方法。該方法不接受任何參數並返回一個標準的消息對象。

我可以建立這一系列對起訂量方法的期望?

+0

+1因爲起訂量真棒;-) – toxvaerd 2009-06-12 09:36:19

回答

5

是啊,這是可能的,如果你不介意通過幾個小鐵圈跳。我之前爲我的一個項目完成了這項工作。好的這裏是基本的技術。我只是測試它在Visual Studio 2008中,這一點也適用:

var mockMessage1 = new Mock<IMessage>(); 
var mockMessage2 = new Mock<IMessage>(); 
var mockMessage3 = new Mock<IMessage>(); 

var messageQueue = new Queue<IMessage>(new [] { mockMessage1.Object, mockMessage2.Object, mockMessage3.Object }); 

var mockMsmqWrapper = new Mock<IMsmqWrapper>(); 

mockMsmqWrapper.Setup(x => x.GetMessage()).Returns(() => messageQueue.Dequeue()).Callback(() => 
{ 
    if (messageQueue.Count == 0) 
     mockMsmqWrapper.Setup(x => x.GetMessage()).Throws<MyCustomException>(); 
}); 

的幾個注意事項:

  1. 您不必返回嘲笑的消息,但如果你想驗證預期是非常有用也可以查看每條消息以查看是否調用了某些方法或設置了屬性。
  2. 排隊的想法不是我自己的,只是我從博客文章中得到的一個提示。
  3. 爲什麼我扔MyCustomException的異常的原因是因爲Queue類自動拋出一個InvalidOperationException異常。我想確保模擬的MsmqWrapper對象由於Moq而引發異常,而不是因爲隊列用完了項目。

下面是作品的完整代碼。請記住,這個代碼是在一些地方難看,但我只是想告訴你如何可以這樣測試:

public interface IMsmqWrapper 
{ 
    IMessage GetMessage(); 
} 

public class MsmqWrapper : IMsmqWrapper 
{ 
    public IMessage GetMessage() 
    { 
     throw new NotImplementedException(); 
    } 
} 

public class Processor 
{ 
    private IMsmqWrapper _wrapper; 
    public int MessagesProcessed { get; set; } 
    public bool ExceptionThrown { get; set; } 

    public Processor(IMsmqWrapper msmqWrapper) 
    { 
     _wrapper = msmqWrapper;   
    } 

    public virtual void ProcessMessages() 
    { 
     _wrapper.GetMessage(); 
     MessagesProcessed++; 
     _wrapper.GetMessage(); 
     MessagesProcessed++; 
     _wrapper.GetMessage(); 
     MessagesProcessed++; 

     try 
     { 
      _wrapper.GetMessage(); 
     } 
     catch (MyCustomException) 
     { 
      ExceptionThrown = true; 
     } 
    } 
} 

[Test] 
public void TestMessageQueueGetsExhausted() 
{ 
    var mockMessage1 = new Mock<IMessage>(); 
    var mockMessage2 = new Mock<IMessage>(); 
    var mockMessage3 = new Mock<IMessage>(); 

    var messageQueue = new Queue<IMessage>(new [] { mockMessage1.Object, mockMessage2.Object, mockMessage3.Object }); 

    var mockMsmqWrapper = new Mock<IMsmqWrapper>(); 
    mockMsmqWrapper.Setup(x => x.GetMessage()).Returns(() => messageQueue.Dequeue()).Callback(() => 
    { 
     if (messageQueue.Count == 0) 
      mockMsmqWrapper.Setup(x => x.GetMessage()).Throws<InvalidProgramException>(); 
    }); 

    var processor = new Processor(mockMsmqWrapper.Object); 

    processor.ProcessMessages(); 

    Assert.That(processor.MessagesProcessed, Is.EqualTo(3)); 
    Assert.That(processor.ExceptionThrown, Is.EqualTo(true)); 
}