de-vraag
  • 質問
  • タグ
  • ユーザー
通知:
報酬:
登録
登録すると、質問に対する返答やコメントが通知されます。
ログイン
すでにアカウントをお持ちの方は、ログインして新しい通知を確認してください。
追加された質問、回答、コメントには報酬があります。
さらに
ソース
編集
 drstevens
drstevens
質問

無名関数からIt.Is ...()が呼び出されたときにMoqのセットアップ/検証マッチャーが失敗するのはなぜですか?

moqとのマッチングのために、かなり複雑な式ツリーの作成を単純化しようとすると、私はいくつかの奇妙な動作に遭遇しました。

私が下に定義されている単純なインタフェースを嘲笑していると仮定します

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

次のコードは5つのテストを表しています。 mockSender.Setup(...)のそれぞれに対して1つのテスト。失敗したとマークされたテストが失敗する理由を誰でも説明できますか?

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

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

    //fails
    var sendMatch = It.IsAny();
    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();
}

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

Edit: I know about Mock.Of<..>(..) and normally prefer to use it but in this case it is not an option.

5 2011-10-27T21:02:00+00:00 2
 drstevens
drstevens
編集された質問 27日 10月 2011 в 9:29
プログラミング
c#
moq
John Foster
2日 11月 2011 в 9:01
2011-11-02T21:01:14+00:00
さらに
ソース
編集
#56793156

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

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

ソースを参照する: -

  • It.IsAny matchers are detected by compiling and executing the expression that is passed as the parameter and looking for any matches (see here).
  • The above step only takes place for method calls and member accesses

だから心にそれを....

  1. Second test fails because the It.IsAny method has been evaluated outside of the matcher factory. As such you have a MemberAccess expression to 0.
  2. Third test passes because SendMatchFromMethod is treated as a method call expression and the call is evaluated inside the MatcherFactory.
  3. Fourth test fails for the same reason as the second, the function has already evaluated and Moq can't detect you've actually called It.Is
  4. Fifth test fails because the Expression is treated as a Function Invocation and Moq does not perform the matcher check for this type of expression.

正直言って4回目のテストは合格しなければならないでしょう。おそらくちょうどそれが端の場合であるからといって、それが中断されているように見えるかもしれません。

Finally Match.Create or MatchAttribute can be used to deal with complex predicates, perhaps they might fit your use case?

6
0
Joel C
27日 10月 2011 в 10:08
2011-10-27T22:08:13+00:00
さらに
ソース
編集
#56793155

This seems to be very similar to a situation I ran into a while ago: Moq unit test with It.IsAny() fails

The issue seems to be with when It.IsAny() gets evaluated. With the 2 tests that pass, it's getting evaluated inside of Setup(...), which works fine. In the first 2 tests that fail, it's getting evaluated outside the scope of Setup(...), so it fails to evaluate correctly. What's probably getting stored in your variable is the result of It.IsAny(), which will be the default value for an int (0).

I don't know the exact reason why the last test would fail, but it could be either that as an optimization your static Func gets evaluated before Setup(...) executes, or it could be that it gets evaluated after Setup(...), but either way it's happening outside of Setup(...).

3
0
質問の追加
カテゴリ
すべて
技術情報
文化・レクリエーション
生活・芸術
科学
プロフェッショナル
事業内容
ユーザー
すべて
新しい
人気
1
Денис Анненский
登録済み 1日前
2
365
登録済み 5日前
3
True Image
登録済み 6日前
4
archana agarwal
登録済み 1週間前
5
Maxim Zhilyaev
登録済み 1週間前
© de-vraag :年
ソース
stackoverflow.com
ライセンス cc by-sa 3.0 帰属