2011-10-27 15 views
4

moqとのマッチングでセットアップ/ベリファイ用にかなり複雑な式ツリーを簡単に作成しようとすると、 。 匿名関数からIt.Is ...()が呼び出されたときにMoqのセットアップ/ベリファイマッチャーが失敗する理由

は、私は次のコードは、5つのテストを表し

public interface IService 
{ 
    int Send(int value); 
} 

の下に定義されたシンプルなインタフェースをからかっていたと。 mockSender.Setup(...)のそれぞれに対して1つのテスト。失敗したとマークされたテストが失敗する理由を誰でも説明できますか?

[Test] 
public void TestInlineSetup() 
{ 
    const int expected = 5; 
    var mockSender = new Mock<IService>(MockBehavior.Loose); 

    //passes 
    mockSender.Setup(s => s.Send(It.IsAny<int>())).Returns(expected); 

    //fails 
    var sendMatch = It.IsAny<int>(); 
    mockSender.Setup(s => s.Send(sendMatch)).Returns(expected); 

    //passes 
    mockSender.Setup(s => s.Send(SendMatchFromMethod())).Returns(expected); 

    //fails 
    var sendMatch = SendMatchFromMethod(); 
    mockSender.Setup(s => s.Send(sendMatch)).Returns(expected); 

    //fails (this is somewhat contrived, but I have reasons for wanting to curry this) 
    mockSender.Setup(s => s.Send(SendMatchFromCurriedMethod()())).Returns(expected); 

    Assert.That(mockSender.Object.Send(expected), Is.EqualTo(expected)); 
} 

public static int SendMatchFromMethod() 
{ 
    return It.IsAny<int>(); 
} 

public static Func<int> SendMatchFromCurriedMethod() 
{ 
    return() => It.IsAny<int>(); 
} 

編集:私はMock.Of < ..>(..)を知っていると、通常はそれを使用することを好むが、この場合には、それはオプションではありません。

答えて

4

問題は、Moqが提供された式ツリーを解析してパラメータマッチャーを作成しようとしていることに起因します。あなたはここにソースを見つけることができます: -

http://code.google.com/p/moq/source/browse/trunk/Source/MatcherFactory.cs

ソースを参照: -

  • It.IsAny<int>マッチャーをコンパイルし、パラメータとして渡された式を実行し、任意の一致を探すことにより検出され、 (here参照)。
  • It.IsAny<int>方法はマッチャーの外で評価されているので、

    1. 第二に、テストが失敗した....上記のステップは、メソッド呼び出しのために行われ、メンバーはこのことを念頭に置いてそう

にアクセス工場。そのため、MemberAccess式は0になります。

  • SendMatchFromMethodがメソッド呼び出し式として扱われ、呼び出しがMatcherFactory内で評価されるため、3番目のテストが合格になります。第四の試験が第二と同じ理由で失敗した、機能が既に評価されており、部品番号は、あなたが実際に式が関数呼び出しとして処理され、部品番号がないのでIt.Is<Any>
  • フィフステストが失敗した呼んでいる検出することはできません
  • このタイプの式のマッチャーチェックを実行します。
  • 正直言って、4番目のテストは合格しなければならず、ちょうどそれがちょっとしたエッジケースだからといって、それが中止されたように見えます。

    最後にMatch.Create<T>またはMatchAttributeは、複雑な述語を処理するために使用できます。

    3

    これは、私はしばらく前に走った状況と非常に似ているように思える:Moq unit test with It.IsAny<DateTime>() fails

    問題がIt.IsAny<int>()が評価されますときにあると思われます。 2つのテストが合格すると、Setup(...)の内部で評価されています。これはうまくいきます。失敗した最初の2つのテストでは、Setup(...)の範囲外で評価されているため、正しく評価されません。あなたの変数におそらく格納されているのはIt.IsAny<int>()の結果で、これはint0)のデフォルト値になります。

    私は最後のテストが失敗する理由の正確な理由は分からないが、それは最適化として、あなたの静的Func<int>Setup(...)実行前に評価されることをどちらかの可能性があり、または、それがSetup(...)後に評価されることをあってもよいが、どちらかの可能性それはSetup(...)の外で起きています。

    +0

    正解ですが、It.IsAny <>を使うことはできません。 – aqwert

    関連する問題