NSubstituteモックのメソッドが特定の配列引数で呼び出されていることを確認したいのですが。
インターフェイスIProcessor
にメソッドvoid ProcessSomething(Foo[] something])
があるとします。テスト中のクラスの名前がCommander
だとします。私はこのように私のテストを設定しました:
_//prepare
var processor = Substitute.For<IProcessor>;
var commander = new Commander(processor);
var foo1 = new Foo("alpha");
var foo2 = new Foo("bravo");
var foos = new [] {foo1, foo2};
//act
commander.DoSomething(foo1, foo2);
//verify
processor.Received().ProcessSomething(foos); // FAILS
_
Received()
呼び出しは次のエラーで失敗します:
_NSubstitute.Exceptions.ReceivedCallsException : Expected to receive a call matching:
ProcessSomething(Foo[])
Actually received no matching calls.
Received 1 non-matching call (non-matching arguments indicated with '*' characters):
ProcessSomething(*Foo[]*)
_
これは、ProcessSomethingがfoos
以外の配列で呼び出されたように見えますよね?
まあ、代わりにこれをテストする場合、Arg.Do()
を使用して引数値をキャプチャすると、成功します。
_//prepare
//... as before
var actualFoos = null;
processor.ProcessSomething(Arg.Do<Foo[]>(x => actualFoos = x));
//act
commander.DoSomething(foo1, foo2);
//verify
Assert.That(actualFoos, Is.EqualTo(foos)); // SUCCEEDS
_
したがって、引数をキャプチャしてそれを(この例ではNUnitと)比較して機能しますが、受信した呼び出しの検証は失敗します。
これはNSubstituteのバグですか、それとも間違って使用していますか?
私は、あなたのCommander
オブジェクトが引数を取り、それらを配列に入れて、Processor
モックを呼び出すために使用することを想定しています。
foos
変数は、セットアップで作成する別の配列です。配列は、同じ要素があったとしても、互いに等しいとは見なされません。そのため、NSubstituteは期待値を受け取っていない(同じ要素を含む別の配列を受け取った)と文句を言います。
編集:このバージョンを試してください:
//prepare
var processor = Substitute.For<IProcessor>;
var commander = new Commander(processor);
var foo1 = new Foo("alpha");
var foo2 = new Foo("bravo");
var foos = new [] {foo1, foo2};
//act
commander.DoSomething(foo1, foo2);
//verify
processor.Received().ProcessSomething(Arg.Is<Foo[]>(foos2 => foos.SequenceEqual(foos2));
これには、System.Linq
名前空間をインポートする必要があります