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?

War es hilfreich?

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

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top