2

NSubstituteを使用して出力パラメーターを持つメソッドをモックするときの状況に遭遇しました。テキストで説明するのに最適な方法がわからないので、いくつかの工夫された例とテストケースを使用します...

この不自然な例では、のNSubstituteモックを使用しますIDictionary<string, string>

private static IDictionary<string, string> GetSubstituteDictionary()
{
    IDictionary<string, string> dict = Substitute.For<IDictionary<string, string>>();

    string s;
    dict.TryGetValue("key", out s).Returns(ci => { ci[1] = "value"; return true; });

    return dict;
}

さて、このモックオブジェクトを簡単な方法で使用すると、期待どおりに戻ります。

[Test]
public void ExampleOne()
{
    var dict = GetSubstituteDictionary();

    string value;
    bool result = dict.TryGetValue("key", out value);

    Assert.That(result, Is.True); // this assert passes.
    Assert.That(value, Is.EqualTo("value")); // this assert passes.
}

ただし、forループで同じコードを呼び出すと、予期しない動作が発生します。

[Test]
public void ExampleTwo()
{
    var dict = GetSubstituteDictionary();

    for (int i = 0; i < 2; i++)
    {
        string value;
        bool result = dict.TryGetValue("key", out value);

        Assert.That(result, Is.True); // this assert FAILS - unexpected!
        Assert.That(value, Is.EqualTo("value")); // this assert still passes.
    }
}

特に、Assert.That(result, Is.True);アサーションはループの最初の反復で渡されますが、2番目(およびそれ以降)の反復では失敗します。

ただし、string value;行をに変更するとstring value = null;、すべての反復でアサーションが渡されます。

この異常の原因は何ですか?これは、欠落しているC#forループのセマンティクスが原因ですか、それともNSubstituteライブラリの問題ですか?

4

1 に答える 1

6

その理由は、value変数がループ内で変更され(出力パラメーターを介して設定される)、スタブアウトした呼び出しと一致しなくなるためです。

を使用してみることができ.ReturnsForAnyArgs()ますが、引数マッチャーを使用するのではなく、スタブ内のキーを確認する必要があります。

于 2012-07-26T03:34:47.987 に答える