2009-06-12 12 views
6

MSMQにラッパーを嘲笑しています。ラッパーは、単にMessageQueueクラスの静的メソッドを直接呼び出すオブジェクトインスタンスを作成することを許可します。良い結果が得られ、Moqからスローされた例外を得ることができます

私は枯渇するためにキューを読むことをテストしたいと思います。これを行うには、模擬ラッパーがいくつかの良い結果を返し、同じメソッドへの4回目の呼び出しで例外をスローしたいと思います。このメソッドはパラメータを受け付けず、標準のメッセージオブジェクトを返します。

Moqのメソッドでこの一連の期待を設定することはできますか?

+0

1部品番号が素晴らしいですので – toxvaerd

+0

それについて教えてください:このコードはいくつかの場所で醜いですが、私はちょうどこれをテストすることができる方法をお見せしたかったことを覚えておいてください! 1年以上にわたり、私はここでは名前を残さないであろう特定の商品を使用し、私は嘲笑した。私は毎回マニュアルを毎回読んで再読しなければなりませんでした。 Moqは新鮮な空気のような呼吸です。私は数分でそれを使用することができましたが、ドキュメントを読む必要はほとんどありません。 –

+0

私はRhinoMockを使用していましたが、私はMoqに比較して、自分の知識を広める方法を知りたいと思っていました。私は今変換しています - 私はMoqの構文がコードをスキャンするときに読みやすくなっています。 – BlackWasp

答えて

5

これは、マイナーなフープを飛び越えても構いません。以前私のプロジェクトの1つでこれをやったことがあります。ここでは基本的なテクニックがあります。私はただの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をスローするためです。私は、Mockされた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)); 
} 
関連する問題