2012-10-02 6 views
30

Ich möchte überprüfen, dass eine Methode auf meinem NSubstitute Mock mit einem bestimmten Array-Argument aufgerufen wird.NSubstitute: Überprüfen empfangener Methoden mit Array-Argumenten

Angenommen, die Schnittstelle, IProcessor, hat eine Methode void ProcessSomething(Foo[] something]). Sagen Sie, meine Klasse im Test heißt Commander. Ich habe meine Prüfung wie folgt auf:

//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() Aufruf 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[]*) 

So sieht das wie ProcessSomething mit einigen Array anders als foos direkt aufgerufen wurde?

Nun, wenn ich diese wie stattdessen testen, wo ich das Argument Wert mit Arg.Do() erfassen, 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 

Also das Argument zu erfassen und sie für die Gleichstellung (mit NUnit in diesem Beispiel) arbeitet zu vergleichen, aber das Überprüfen des empfangenen Anrufs schlägt fehl.

Ist das ein Fehler in NSubstitute, oder verwende ich es falsch?

Antwort

36

Ich nehme an, dass Ihr Commander Objekt die Argumente übernimmt und sie in ein Array stellt, das es dann verwendet, um den Processor Mock aufzurufen.

Ihre foos Variable ist ein weiteres Array, das Sie in Ihrem Setup erstellen. Arrays sind nicht gleich, auch wenn sie dieselben Elemente haben. Also wird sich NSsubstitute beschweren, dass es nicht den erwarteten Wert erhalten hat (es hat ein anderes Array erhalten, das zufällig dieselben Elemente enthält).

Edit: diese Version Versuchen:

//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 Namespace

+1

Nach Ihrer Antwort zu lesen, schaute ich in die NUnit Quelle, und sah, dass Is.EqualTo (via EqualConstraint) Überprüft die Sammlungen auf Gleichheit, indem Elemente in den Sammlungen verglichen werden. Deshalb hat die Erfassung des Werts und der Überprüfung funktioniert. Jetzt ist die Frage, warum nicht .Net Sammlungen Equals implementieren, aber das ist ein Problem für einen anderen Tag. – Jimothy

+0

Das ist eine schöne Syntax. So viel sauberer als RhinoMocks –

Verwandte Themen