2012-10-02 15 views
30

Quiero verificar que se llame a un método en mi simulacro NSubstitute con un argumento de matriz particular.NSustituir: Comprobación de los métodos recibidos con argumentos de matriz

Digamos que la interfaz, IProcessor, tiene un método void ProcessSomething(Foo[] something]). Supongamos que mi clase bajo prueba se llama Commander. He definido mi prueba de la siguiente manera:

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

La llamada falla con 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[]*) 

Así que esto parece ProcessSomething fue llamado con un poco de variedad distinta de foos, ¿verdad?

Bueno, si en lugar de probar esto, dónde puedo capturar el valor del argumento utilizando Arg.Do(), tiene éxito:

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

Así capturar el argumento y comparándolo por la igualdad (con NUnit en este ejemplo) funciona, pero verifica que la llamada recibida falla.

¿Esto es un error en NSubstitute, o lo estoy usando mal?

Respuesta

36

Supongo que su objeto Commander tomará los argumentos y los colocará en una matriz que luego utilizará para invocar el simulacro Processor.

Su variable foos es otra matriz que usted crea en su configuración. Las matrices no se comparan entre sí, incluso si tienen los mismos elementos. Así que NSubstitute se quejará de que no recibió el valor esperado (recibió otra matriz que por casualidad contenía los mismos elementos).

Editar: Prueba esta versión:

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

Para ello es necesario importar el espacio de nombres System.Linq

+1

Después de leer su respuesta, miré en la fuente de NUnit, y vi que Is.EqualTo (a través de EqualConstraint) verifica la igualdad de las colecciones al comparar elementos en las colecciones. Es por eso que capturar el valor y verificar funcionaba. Ahora la pregunta es, ¿por qué las colecciones .Net no implementan Equals, pero ese es un problema para otro día. – Jimothy

+0

Esa es una sintaxis encantadora. Mucho más limpio que RhinoMocks –

Cuestiones relacionadas