Aislar el código en pruebas con Microsoft Fakes

El aislamiento de código es una estrategia de prueba que se suele implementar con herramientas como Microsoft Fakes, donde el código que se está probando está separado del resto de la aplicación. Esta separación se logra reemplazando las partes de la aplicación que interactúan con el código en fase de prueba por códigos auxiliares o correcciones de compatibilidad (shim). Se trata de pequeños fragmentos de código controlados por las pruebas, que simulan el comportamiento de las partes reales a las que reemplazan.

La ventaja de este método es que permite centrarse en probar la funcionalidad específica del código de forma aislada. Así, si se produce un error en una prueba, se sabe que la causa está dentro del código aislado, y no en otro sitio. Además, el uso de códigos auxiliares y de correcciones de compatibilidad (shim), proporcionados por Microsoft Fakes, permite probar el código aunque haya otras partes de la aplicación que todavía no funcionen.

Requisitos

  • Visual Studio Enterprise
  • Un proyecto de .NET Framework
  • La compatibilidad con proyectos de .NET Core, .NET 5.0 o versiones posteriores y de estilo SDK, que se encontraba en versión preliminar en Visual Studio 2019 Update 6, ya está habilitada de forma predeterminada en Update 8. Para obtener más información, vea Microsoft Fakes para .NET Core y proyectos de tipo SDK.

Nota

La generación de perfiles con Visual Studio no está disponible para las pruebas que usan Microsoft Fakes.

El papel de Microsoft Fakes en el aislamiento de código

Microsoft Fakes desempeña un papel clave en el aislamiento de código, ya que proporciona dos mecanismos: códigos auxiliares y correcciones de compatibilidad (shim).

  • Códigos auxiliares: sirven para reemplazar una clase por un pequeño sustituto que implementa la misma interfaz. Esto requiere que la aplicación se diseñe de modo que cada componente dependa solo de las interfaces, no de otros componentes.

  • Correcciones de compatibilidad (shim): se usan para modificar el código compilado de la aplicación en tiempo de ejecución. En lugar de llamar al método concreto especificado, la aplicación ejecuta el código de la corrección de compatibilidad (shim) que la prueba proporcione. Las correcciones de compatibilidad (shim) pueden reemplazar las llamadas a ensamblados que no es posible modificar, como los ensamblados .NET.

Los códigos auxiliares se suelen usar en llamadas dentro de la solución de Visual Studio, mientras que las correcciones de compatibilidad (shim) se emplean en llamadas a otros ensamblados a los que se hace referencia. El motivo es que, en su solución, es recomendable desacoplar los componentes definiendo las interfaces como el código auxiliar lo requiere. Sin embargo, a menudo los ensamblados externos no incluyen definiciones de interfaz independientes, por lo que se usan correcciones de compatibilidad (shim) en su lugar.

Diagram that show Fakes replacing other components.

Recomendaciones sobre cuándo usar códigos auxiliares

Normalmente, los códigos auxiliares se usan en llamadas dentro de la solución de Visual Studio, ya que conviene desacoplar los componentes definiendo interfaces de la manera que el código auxiliar lo requiera. Sin embargo, los ensamblados externos (como System.dll) no se suelen proporcionar con definiciones de interfaz independientes, por lo que en estos casos se usarían correcciones de compatibilidad (shim) en su lugar.

El uso de códigos auxiliares conlleva diseñar la aplicación de modo que no exista ninguna dependencia entre los distintos componentes, sino solo de las definiciones de interfaz. Este desacoplamiento hace que la aplicación sea más sólida y flexible y permite conectar el componente en pruebas a las implementaciones de código auxiliar de las interfaces con fines de realización de pruebas.

En la práctica, se pueden generar tipos de código auxiliar a partir de las definiciones de interfaz de Visual Studio y, seguidamente, reemplazar el componente real por el código auxiliar de la prueba.

Recomendaciones sobre cuándo usar correcciones de compatibilidad (shim)

Mientras que los códigos auxiliares se suelen usar en llamadas dentro de la solución de Visual Studio, las correcciones de compatibilidad (shim) se emplean generalmente en llamadas a otros ensamblados a los que se hace referencia. Esto se debe a que los ensamblados externos, como System.dll, no suelen proporcionarse con definiciones de interfaz independientes, por lo que deben usarse correcciones de compatibilidad (shim) en su lugar.

Con todo, hay algunos factores que se deben tener en cuenta al usar correcciones de compatibilidad (shim):

Rendimiento: las correcciones de compatibilidad (shim) se ejecutan más lentamente porque reescriben el código en tiempo de ejecución. Los códigos auxiliares no tienen esta sobrecarga de rendimiento y son tan rápidos como los métodos virtuales.

Métodos estáticos, tipos sellados: los códigos auxiliares solo se pueden usar para implementar interfaces. En consecuencia, los tipos de código auxiliar no se pueden usar con métodos estáticos, métodos no virtuales, métodos virtuales sellados, métodos de tipos sellados, etc.

Tipos internos: el código auxiliar y las correcciones de compatibilidad (shim) se pueden usar con los tipos internos que se hacen accesibles mediante el atributo de ensamblado InternalsVisibleToAttribute​.

Métodos privados: las correcciones de compatibilidad (shim) pueden reemplazar llamadas a métodos privados si todos los tipos de la firma de método son visibles. Los códigos auxiliares solo pueden reemplazar métodos visibles.

Interfaces y métodos abstractos: los códigos auxiliares proporcionan implementaciones de interfaces y métodos abstractos que se pueden usar en las pruebas. Las correcciones de compatibilidad (shims) no pueden instrumentar interfaces y métodos abstractos, porque no tienen cuerpos de método.


Transición de Microsoft Fakes en .NET Framework a proyectos de estilo SDK

Transición de los proyectos de prueba de .NET Framework que usan Microsoft Fakes a proyectos de .NET Framework, .NET Core o .NET 5+ de estilo SDK

Solo necesitará realizar unos pocos cambios en el entorno de .NET Framework configurado para Microsoft Fakes para llevar a cabo la transición a .NET Core o .NET 5.0. Debe tener en cuenta los siguientes casos:

  • Si usa una plantilla de proyecto personalizada, debe asegurarse de que sea de estilo SDK y de que se compile para una plataforma de destino compatible.

  • Hay algunos tipos que ya se encuentran en diferentes ensamblados de .NET Framework y .NET Core/.NET 5.0 (por ejemplo, System.DateTime existe en System/mscorlib en .NET Framework, y en System.Runtime en .NET Core y .NET 5.0); en estos escenarios debe cambiar el ensamblado que se va a imitar.

  • Si tiene una referencia de ensamblado a un ensamblado de Fakes y al proyecto de prueba, es posible que vea una advertencia de compilación que indica que falta una referencia similar a la siguiente:

    (ResolveAssemblyReferences target) ->
    warning MSB3245: Could not resolve this reference. Could not locate the assembly "AssemblyName.Fakes". Check to make sure the assembly exists on disk.
    If this reference is required by your code, you may get compilation errors.
    

    Esta advertencia se debe a los cambios necesarios realizados en la generación de Fakes y se puede omitir. Para evitarla, se puede quitar la referencia de ensamblado del archivo de proyecto, ya que ahora se agrega implícitamente durante la compilación.

Ejecución de pruebas de Microsoft Fakes

Siempre que los ensamblados de Microsoft Fakes estén presentes en el directorio configurado FakesAssemblies (el valor predeterminado es $(ProjectDir)FakesAssemblies), puede ejecutar las pruebas mediante la tarea VSTest.

Para realizar pruebas distribuidas con la tarea VSTest en proyectos de .NET Core y .NET 5+ que usan Microsoft Fakes, se requiere Visual Studio 2019 Update 9 Preview 20201020-06 y versiones posteriores.

Compatibilidad y soporte de Microsoft Fakes en diferentes versiones de .NET y Visual Studio

Microsoft Fakes en proyectos antiguos que tienen como destino .NET Framework (estilo que no sea de SDK).

  • La generación de ensamblados de Microsoft Fakes es compatible con Visual Studio Enterprise 2015 y versiones posteriores.
  • Las pruebas de Microsoft Fakes se pueden ejecutar con todos los paquetes de NuGet Microsoft.TestPlatform disponibles.
  • La cobertura de código es compatible con los proyectos de prueba que usan Microsoft Fakes en Visual Studio Enterprise 2015 y versiones posteriores.

Microsoft Fakes en proyectos de .NET Framework, .NET Core y .NET 5.0 o versiones posteriores de estilo SDK

  • La generación de ensamblados de Microsoft Fakes, en versión preliminar en Visual Studio Enterprise 2019 Update 6, ya está habilitada de forma predeterminada en Update 8.
  • Las pruebas de Microsoft Fakes para los proyectos que tienen como destino .NET Framework pueden ejecutarse con todos los paquetes de NuGet Microsoft.TestPlatform disponibles.
  • Las pruebas de Microsoft Fakes para los proyectos que tienen como destino .NET Core y .NET 5.0 o versiones posteriores pueden ejecutarse con los paquetes NuGet Microsoft.TestPlatform con las versiones 16.9.0-preview-20210106-01 y posteriores.
  • La cobertura de código es compatible con los proyectos de prueba que tienen como destino .NET Framework y que usan Microsoft Fakes en Visual Studio Enterprise 2015 y versiones posteriores.
  • La compatibilidad con la cobertura de código en los proyectos de prueba que tienen como destino .NET Core y .NET 5.0 o versiones posteriores y que usan Microsoft Fakes está disponible en Visual Studio 2019 Update 9 y versiones posteriores.