ASP.NET MVC y otras Yerbas – Parte 4

Sin más que decir volvamos a la acción:

Para una mejor calidad también podemos verlo en HD.

A continuación tenemos una explicación de algunas de las cosas que hemos visto:

  • ¿Cuál es la estructura de un test? Un Test tiene comúnmente la siguiente estructura:
    • Arrange: Creamos todas las precondiciones y entradas necesarias.
    • Act: Realizamos la acción en el objeto que estamos probando.
    • Assert: Verificamos que los resultados que esperamos se han producido.

  • ¿Qué es lo primero que hacemos para agregar alguna funcionalidad? Sin duda alguna, lo primero es realizar el Test.

  • ¿Cómo nombramos al Test? Tener un estándar para los nombres de los test resulta importante ya que nos brinda un descripción entendible por propios y extraños sobre lo que realiza el test. Recuerden los Test son Documentación. La convención de nombre Método_Escenario_ComportamientoEsperado nos ayuda bastante a lograr lo anteriormente mencionado.

  • ¿Qué es lo que probamos primero? De todas las opciones que tenemos, probamos la más simple, pero que cree funcionalidad real o valor.

    Se acuerdan del Kata de Números Primos, la primera prueba que realizamos fue verificar que el número 1 nos devolvía una lista vacía. No comenzamos probando que el número 9 nos devolviera 2 primos, ni tampoco que un número menor a uno 1 arrojara una excepción.

    Pero, ¿porqué comenzamos con la más simple?… Imaginen que hubiéramos comenzado probando cuales son los números primos de 9, la cantidad de código escrito habría sido mucho mayor en relación a una prueba de los números primos de 1 y por lo tanto habría transcurrido mucho más tiempo en completarse el ciclo de TDD ( Red – Green – Refactor) y en obtener el feedback que nos aporta el mismo.

    Espérate un momento!, en el video no todas las pruebas han comenzado con la opción más simple….Tomemos como ejemplo un método que suma 2 números (x, y), entonces según lo dicho anteriormente el camino más simple sería crear un test que verifique 0+0=0 y en el código de producción retornamos 0, nuestro siguiente test podría ser que 1+0=1 y en el código de producción retornamos x, por ultimo probar que 2+1=3 y en el código retornamos x+y. (este camino se parece bastante a nuestro Kata verdad). Pero creo que todos sabemos que la implementación a un método de suma es x+y. Entonces en estos casos donde la implementación es un poco obvia, no tenemos que pedir permiso a varios test para poder escribir el código de producción.

    Algo parecido sucede en nuestro ejemplo, ya que de alguna manera se tiene una noción de como los servicios y repositorios interactúan juntos; de igual manera, tampoco nos preocupamos de temas más complejos como validaciones ni reglas de negocios. Por lo tanto nos sentimos con cierto nivel de confianza para dar pasos ligeramente más grandes pero de manera muy rápida.

    Como sabemos que podemos optar por esto, una pista muy simple la encontramos al escribir el test, si en ese momento nos ponemos a pensar mucho en los detalles (nombre, entradas, salidas) es una señal de que la implementación no es tan simple como parece. Asimismo si nos sentimos seguros de dar pasos más grandes y observamos que los test se rompen muy seguido, quizás debamos hacer pasos más pequeños.

  • ¿Qué es lo primero que escribimos en el test? De abajo para arriba, lo primero es el Assert. Esta es una práctica que he encontrado muy útil, ya que al realizar el test, nuestro cerebro  se pone a pensar muchas cosas al mismo tiempo: ¿cómo nombramos los elementos?, ¿cómo lo voy a verificar?, ¿qué me sugieren hacer los otros test?, etc.

    Entonces al realizar el Assert primero, aislamos uno de los problemas del resto: ¿cómo lo voy a verificar?, y en base a esto construimos el resto del test:

    • ¿Cómo lo voy a verificar? Probando que se llame al método Agregar del Repositorio.
    • ¿Dónde se llama al método Agregar? Desde el método Registrar de la clase AdministrarEmpresa.
    • ¿Qué se requiere para llamar al método Registrar? Pasarle un objeto Empresa.

    Está práctica junto con la anterior convención de nombres son una combinación muy buena. Asimismo te permite aprovechar bastante las herramientas que te otorga el entorno de desarrollo (Resharper Rulz!).


  • Volvamos por un momento al post anterior, ahí hemos observado el uso de tests para construir una clase que no depende internamente de ninguna otra.

    image 

    Pero en la cruel realidad no todo es tan bonito y simple. Las clases dentro de nuestras aplicaciones tienen dependencias para poder funcionar (bases de datos, web services, etc)

    image

    Y esto se pone peor, ya que esas dependencias tienen también sus dependencias, y estas dependencias tienen más dependencias y así sucesivamente. Entonces crear un test puede parecer que se vuelve en una tarea complejísima y posiblemente imposible.

    ¿Cuál es la solución? Eliminar esas dependencias, pero sin esas dependencias nuestra clase no va a funcionar, reemplacemos esas dependencias por algo más simple; y como hacemos para que la clase utilice esas nuevas dependencias, hagamos que el test sea quien controle esas dependencias:

    image

    Aquí es donde entran los famosos Test Doubles (“Generic term for any kind of pretend object used in place of a real object for testing purposes” – Martin Fowler ).

    En nuestro ejemplo hemos usado 2 Test Doubles (Other Simple Class), esto debido a que necesitamos probar nuestras clases RegistrarEmpresa (Class Under Test) y ReclutarPersonal (Class Under Test), y ambas clases dependen de un implementación de IEmpresaRepository (Other Class) para persistir la información.

    Estos Test Doubles los podemos identificar fácilmente ya que son los objetos que tienen los nombres más raros de todo el ejemplo: mockEmpresaRepository y stubEmpresaRepository.

    Pero, ¿porqué uno se llama mock y el otro stub ? Para darnos cuenta entre la diferencia que tienen, podríamos definirlos de manera muy simple:

    • Mock: Es el Test Double sobre el cuál realizamos un Assert. Ejm:
      mockEmpresaRepository.AssertWasCalled(x => x.Agregar(empresa));
      Estamos verificamos que el método Agregar del IEmpresaRepository se ha llamado dentro del método que estamos probando.

    • Stub: Es el Test Double que nos permite poder realizar el test. Ejm:
      stubEmpresaRepository.Expect(x => x.Obtener(idEmpresa)).Return(empresa);
      Estamos indicando que cuando se llame el método Obtener del IEmpresaRepository nos devuelva una empresa cualquiera y así la prueba del método pueda continuar.

Bueno, hasta aquí hemos visto algunos temas del video, pero aún nos falta otros que dejaremos para un siguiente post. Espero les sirva de algo mi pequeño granito de arena. Y les prometo mejorar mi redacción.

No se olviden de ver el resto de las serie ASP.NET MVC y otras Yerbas.
Saludos.