2012-10-02 12 views
30

Chcę sprawdzić, czy metoda na mojej próbce NSubstitute jest wywoływana z konkretnym argumentem tablicy.NSubstitute: Sprawdzanie odebranych metod za pomocą argumentów tablicy

Powiedz, że interfejs, IProcessor, ma metodę void ProcessSomething(Foo[] something]). Powiedzmy, że moja testowana klasa nazywa się Commander. Założyłem mój test takiego:

//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() połączenia nie powiedzie się z:

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

Tak to wygląda ProcessSomething nazwano z jakiejś tablicy innej niż foos, prawda?

Cóż, gdybym zamiast przetestować ten podobnych, gdzie uchwycić wartość argumentu używając Arg.Do(), powiedzie się:

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

Więc przechwytywanie argument i porównując ją do równości (z NUnit w tym przykładzie) działa, ale weryfikacja odebranego połączenia nie powiedzie się.

Czy to błąd w NSubstitute, czy też używam go nieprawidłowo?

Odpowiedz

36

Zakładam, że Twój obiekt Commander przejmie argumenty i umieści je w tablicy, którą następnie użyje do wywołania makiety Processor.

Twoja zmienna foos to kolejna tablica, którą utworzysz w swoim setupie. Tablice nie są równe sobie, nawet jeśli mają te same elementy. So NSubstitute będzie narzekał, że nie otrzymał oczekiwanej wartości (otrzymał inną tablicę, która zawierała te same elementy).

Edit: Spróbuj tej wersji:

//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)); 

Wymaga to importowanie przestrzeni nazw

+1

System.Linq Po przeczytaniu swoją odpowiedź, spojrzałem do źródła NUnit i zobaczył, że Is.EqualTo (przez EqualConstraint) sprawdza kolekcje pod kątem równości, porównując elementy w kolekcjach. Dlatego uchwycenie wartości i sprawdzanie działało. Teraz pytanie brzmi: dlaczego kolekcje .Net nie implementują równań, ale jest to problem na inny dzień. – Jimothy

+0

To piękna składnia. O wiele czystsze niż RhinoMocks –

Powiązane problemy