Introducción a Fakes (UnitTest – .NET)

En algunas ocasiones cuando estamos creando pruebas unitarias se nos puede presentar la situación en la que necesitamos tener datos fijos para poder realizar las pruebas o bien simular funcionalidades que aún no se han implementado, por ejemplo si trabajamos con una fecha y debemos de verificar si el día de la semana es Lunes no vamos a esperar hasta el Lunes para ejecutar la prueba o bien si tenemos una función que devuelve un número aleatorio podemos indicarle que para las pruebas retorne cierto valor y así verificar que todo funcione como se debe. En un artículo anterior aprendimos acerca de Unit Test y en este nos enfocaremos en Ensamblajes Fakes que nos permiten aislar el código en tiempo de pruebas.

Los ensamblajes Fakes se dividen en:

  1. Shim: Se utilizan cuando vamos hacer un test de una clase que no hemos creado y que no podemos modificar por ejemplo System
  2. Stub: Se utilizan cuando nosotros creamos las clases a utilizar, por ejemplo la clase Persona, Auto y vamos a testear sus métodos, suelen llevar más trabajo sin embargo nos inducen a buenas prácticas en desarrolo de software.

Nota: Si desean obtener más información pueden visitar el sitio oficial.

Shim

Primero debemos de contar con una solución que tenga dos proyectos:

  1. Aplicación de consola o Librería de clases portables, dentro de ella crearemos una clase llamada Gift.
  2. Pruebas unitarias para el proyecto anterior.

00a

En la clase Gift vamos agregar un método IsWeekend que nos indicará si el día de hoy es fin de semana (para este caso consideraremos los días Sábado y Domingo, en otras culturas  es diferente).


    public class Gift
    {
        public bool IsWeekend ()
        {
            return DateTime.Now.DayOfWeek == DayOfWeek.Saturday || DateTime.Now.DayOfWeek == DayOfWeek.Sunday;
        }
    }

Ahora en el proyecto de Unit Test vamos agregar la referencia a la aplicación de consola o PCL, damos click derecho sobre el proyecto de UnitTest y seleccionamos “Agregar referencia…”

04

Seleccionamos la sección de proyectos y luego marcamos el proyecto al cual realizaremos las pruebas

00d

Seguidamenta agregaremos un ensamblaje Fake, en este caso será de System ya que dentro de este dll se encuentra la clase DateTime que estamos utilizando

00b

Ahora nuestro proyecto debe contener una carpeta (Fakes) con algunos archivos

03

Vamos abrir la clase creada por defecto (UnitTest1) en el proyecto de UnitTest y dentro de ella agregamos el siguiente código


public class UnitTest1
    {
        [TestMethod]
        public void TestGiftIsWeekend()
        {
            // Shims solo pueden ser utilizados en ShimsContext:
            using (ShimsContext.Create())
            {
                // Arrange:
                // Shim DateTime.Now para que regrese una fecha fija
                System.Fakes.ShimDateTime.NowGet = () =>
                    { return new DateTime(2016, 5, 21); };

                Gift gift = new Gift();

                // Act:
                bool status = gift.IsWeekend();

                // Assert:
                // Siempre es true si el componente que se prueba funciona
                Assert.AreEqual(true, status);
            }

        }
    }

No vamos a entrar en profundidas de Unit Test ya que en un artículo anterior había comentado el tema, donde si vamos a enforcarnos es en el siguiente código:


// Arrange:
// Shim DateTime.Now para que regrese una fecha fija
System.Fakes.ShimDateTime.NowGet = () =>
{ return new DateTime(2016, 5, 21); };

Básicamente lo que hacemos es indicarle a DateTime que para esta prueba cuando se llame a la función Now retorne la fecha que indicamos a la derecha, para ello creamos una función en lambda que toma cero argumentos y que retorna una fecha con el año, mes y día especificado.

Una vez agregado vamos a ejecutar la prueba y veremos si pasa o no

05

Stub

Trabajaremos en la misma solución, vamos agregar en el proyecto de consola o PCL una interfaz con los métodos en Gift (la implementaremos acá)

    public interface IGift
    {
        bool IsWeekend();

        int BirthYear(int maxValue);
    }

Nuestra clase Gift ahora debe de implementar la interfaz anterior y además agregaremos una función llamada “BirthYear” que recibe un número entero (edad) y dentro de ella restamos el año actual menos la edad enviada para obtener el año de nacimiento.


    public class Gift : IGift
    {

        public bool IsWeekend ()
        {
            return DateTime.Now.DayOfWeek == DayOfWeek.Saturday || DateTime.Now.DayOfWeek == DayOfWeek.Sunday;
        }

        public int BirthYear(int age)
        {
            return DateTime.Now.Year - age;
        }

    }

Ahora vamos a agregar un ensamblaje Fake pero en este caso será de nuestra PCL o proyecto de consola ya que vamos hacer un test de una clase que creamos.

01

De igual manera una vez que se agrega vamos a observar nuevos archivos en la carpeta Fakes

02

Ahora vamos a la clase UnitTest1 y agregamos el siguiente método


        [TestMethod]
        public void TestBirthYear()
        {
            // Arrange:
            StubIGift stubGift = new StubIGift();
            // Shim DateTime.Now para que regrese una fecha fija
            stubGift.BirthYearInt32 = (parameter) => { return 1990; };
            Gift gift = new Gift();

            // Act:
            int year = gift.BirthYear(26);

            // Assert:
            Assert.AreEqual(1990, year);
        }

La parte del código más importante es donde creamos un StubIGift, esta clase es creada cuando agregamos el Fake del proyecto, siempre van a empezar por StubNombreInterfaz. Después modificamos el comportamiento de la función BirthYear para que regrese 1990

Ahora podemos ejecutar las pruebas

03

Bueno los Fakes nos van brindar ventajas a la hora de probar nuestro código y lo mejor es que permiten hacer test simulando funcionalidades que pueden no estar implementadas aún. En GitHub pueden encontrar el código.

Espero que les sea de ayuda, hasta la próxima 🙂

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s