Nsubstitut:Empfangene Methoden mit Array-Argumenten überprüfen
-
12-12-2019 - |
Frage
Ich möchte überprüfen, ob eine Methode in meinem NSubstitute-Mock mit einem bestimmten Array-Argument aufgerufen wird.
Sagen Sie die Schnittstelle, IProcessor
, hat eine Methode void ProcessSomething(Foo[] something])
.Angenommen, meine zu testende Klasse heißt Commander
.Ich habe meinen Test so eingerichtet:
//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
Der Received()
anruf schlägt fehl mit:
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[]*)
Das sieht also so aus, als ob ProcessSomething mit einem anderen Array als aufgerufen wurde foos
, richtig?
Nun, wenn ich das stattdessen so teste, wo ich den Argumentwert mit erfasse Arg.Do()
, es gelingt:
//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
Das Erfassen des Arguments und der Vergleich auf Gleichheit (in diesem Beispiel mit NUnit) funktionieren also, aber die Überprüfung des empfangenen Anrufs schlägt fehl.
Ist das ein Fehler in NSubstitute oder benutze ich ihn falsch?
Lösung
Ich gehe davon aus, dass Ihre Commander
objekt nimmt die Argumente und fügt sie in ein Array ein, mit dem es dann die aufruft Processor
verspotten.
Ihrer foos
variable ist ein weiteres Array, das Sie in Ihrem Setup erstellen.Arrays vergleichen sich nicht gleich, auch wenn sie dieselben Elemente haben.NSubstitute wird sich also beschweren, dass es nicht den erwarteten Wert erhalten hat (es hat ein anderes Array erhalten, das zufällig dieselben Elemente enthielt).
Bearbeiten: Probieren Sie diese Version aus:
//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));
Dies erfordert den Import der System.Linq
Namensraum