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ライブラリの問題ですか?