Al estar trabajando en un proyecto sobre ASP.NET MVC pequeño. Pensé que sería mas fácil animar a escribir pruebas, a personas que no están acostumbradas, si al escribirlas no necesitaran usar librerías externas. Como son los mocking frameworks y las librerías para las aserciones. Así que decidí escribir las pruebas unitarias usando solo las herramientas que me brinda Visual Studio. Eso significa usar msTest y escribir implementaciones falsas de las dependencias de los sistemas bajo prueba.
Llegué a pensar que eso significaría escribir mucho más código ya que tendría que proporcionar varías implementaciones que un mocking framework me ahorraría. Sin embargo he notado que la cantidad de código no es mucho más. Ya que con las mocking frameworks necesitaba hacer más setups dentro del test. Es claro que tiene sus ventajas y desventajas.
Noté que para un programador, que no esta acostumbrado a escribir pruebas unitarias, es fácil entender qué es lo que pasa cuando usamos una implementación falsa donde puede ver el código. A la vez es fácil que escriba sus implementaciones que solo le sirven para pruebas. En ocasiones cuando trataba de explicar TDD (a gente que no esta acostumbrada) usando un mocking framework, u otra librería, notaba que varios se perdían un poco tratando de entender el código de setups de moq o de NSubstitute. Con implementaciones falsas escritas por ellos mismos (o que pueden ver lo que pasa) es más fácil concentrarse en (y encontrarle más sentido a) la prueba.
El método de prueba puede centrarse en los efectos secundarios del sistema bajo prueba, en lugar de la implementación. Es decir no pruebas que realice llamadas a ciertos métodos de las dependencias sino que tenga los efectos secundarios que se espera.
Una de las desventajas es que se necesita escribir la implementación falsa para que la prueba pueda correr y eso hace que pierda un poco el flujo de lo que se esta probando. Al tener que abrir otro archivo y escribir algo de código. Además que terminas con más código que mantener.
Otra es que a pesar de tener una implementación falsa que se puede compartir. De cualquier forma se necesita algo de código en la prueba para cumplir con las precondiciones que la prueba requiere y terminas con la implementación falsa además de código de setup. Otra vez más código que quizás el mocking framework me hubiera ahorrado.
Muy bien! Me parece lo mejor usar la menos cantidad de herramientas posibles.
ResponderBorrarOtra cosa, a veces utilizo las dependencias reales en mis tests, no los llamo de integración para mi son todas especificaciones, si en algunas necesito uso stubs, y en otras puedo usar hasta la bd...
Por otro lado a mi me gusta mas TDD top-down la mayoría de las veces. Por lo tanto al principio de un proyecto no empiezo escribiendo un test de un controller con un mock de un query object... Por que el query object lo hago nacer despues con algún refactoring, entonces es probable que empieze usando la bd o alguna cosa externa. Con esto quiero decir que al principio necesito menos mocks/stubs.
Y lo ultimo, utilizo muchos mas stubs que mocks. Solo podría usar un mock cuando el sistema bajo test es un Command (CQS). Por ejemplo necesito verificar que si el usuario contesta NO a un message box que pide confirmación para eliminar algo, realmente no se elimine.