NSubstitute para Dobles de Prueba

2015-07-05

Como ya había escrito antes, las últimas semanas he estado en un proyecto en el cual aplicaba por primera vez dobles de prueba. Escribí un post sobre lo que eran los stubs, y en los ejemplos usaba una herramienta llamada NSubstitute. Esta herramienta es un framework para crear dobles de pruebas en .NET, no es la única, de hecho la primera opción que me había encontrado era Moq (quizás más común). Después de ver ambas herramientas en acción, me quedo con NSubstitute ya que en mi opinión el código queda más claro, limpio y legible. Veamos un par de ejemplos básicos de cómo se utiliza NSubstitute.

1
var collaborator = Substitute.For<AnyInterface>();

Aquí estamos creando un doble de pruebas de tipo “AnyInterface” (una interfaz cualquiera). Vemos que el código queda bastante claro, básicamente te dice dame un sustituto para “AnyInterface”.

1
2
collaborator.Received().AnyMethod(argument1);
collaborator.DidNotReceive().AnyMethod(argument2);

En este ejemplo, simplemente comprobamos en la primera línea que el colaborador ha recibido una llamada al método “AnyMethod” pasándole por parámetro “argument1”, mientras que en la segunda línea comprobamos que el colaborador no ha recibido ninguna llamada para el mismo método pero pasándole como parámetro “argument2”.

1
collaborator.AnyMethod(argument1).Returns(aResult);

De esta manera creamos un Stub, le estamos diciendo que cuando se llame al método “AnyMethod” pasándole “argument1” queremos que devuelva el “aResult”.

Un caso que encontré curioso es cuando quieres hacer un stub falseando un método asíncrono. La verdad es que este ejemplo no es tan trivial, ya que en Moq por ejemplo, tienes un método “ReturnsAsync” el cual se encarga de esperar a que se termine el método asíncrono y te devuelve su resultado. Sin embargo, en NSubstitute no dispones de este método y si sólo usas el “Returns” como en los ejemplos previos ni siquiera compila ya que se espera que tu método asíncrono devuelva una tarea (Task), por tanto, la manera de hacerlo es decirle que te cree una tarea a partir del resultado esperado. Con el código se entenderá mejor:

1
collaborator.AnyAsyncMethod(argument1).Returns(Task.FromResult(aResult));

Como hemos podido ver es bastante sencillo de usar, he comentado debajo de cada ejemplo lo que hacía por si acaso lee esto alguien que está empezando a ver dobles de pruebas, ya que si ya has tenido algún tipo de experiencia con este tipo de herramientas las líneas quedan bastante claras por sí solas. El último ejemplo, sin embargo, sí consideraba necesario explicarlo mejor ya que como dije antes no es trivial. NSubstite me ha encantado como herramienta y por lo menos yo ya la he añadido a mi repertorio, si queréis saber más podéis ir a la documentación que la verdad está bastante bien.