Primera prueba unitaria con xUnit en .NET

Resumen

Crear tu primera prueba unitaria con xUnit en .NET es más sencillo de lo que parece cuando entiendes la estructura del proyecto, las convenciones de nombres y cómo funciona el atributo Fact. Aquí aprenderás a configurar el proyecto, escribir el primer test y ejecutarlo desde Visual Studio para validar que tu código hace lo que debe hacer.

¿Por qué separar el proyecto de pruebas del proyecto principal?

Una buena práctica en desarrollo .NET es mantener las pruebas en un proyecto independiente y referenciar desde ahí el proyecto que quieres probar. Mezclar la lógica de negocio con los tests genera acoplamiento innecesario y complica el despliegue.

En Visual Studio, dentro de la misma solución, agregas un nuevo proyecto con la opción Add > New Project. Si filtras por la palabra Test, aparecen las plantillas oficiales: MSTest, NUnit y xUnit. Estas plantillas vienen con todas las librerías necesarias preinstaladas, lo que te ahorra configuración manual [02:15].

¿Puedo usar una librería de clases normal en vez de la plantilla de Test? Sí. Puedes crear una Class Library y agregar manualmente los paquetes NuGet de xUnit. La plantilla solo automatiza ese paso.

¿Cómo nombrar el proyecto y las clases de prueba?

Existe un estándar muy claro en la comunidad .NET para nombrar proyectos y clases de testing. Seguirlo te ayuda a que cualquier desarrollador entienda tu estructura al instante.

  • El proyecto de pruebas lleva el mismo nombre del proyecto a probar más la palabra Tests en plural. Ejemplo: StringManipulation.Tests.
  • La clase de pruebas lleva el nombre de la clase a probar más la palabra Test en singular. Ejemplo: StringOperationTest.
  • La clase debe ser public para que el runner pueda ejecutarla. Visual Studio la crea como internal por defecto y eso impide que las pruebas corran [05:40].

Después de crear el proyecto con la plantilla xUnit Test Project y seleccionar la versión de .NET (en este caso .NET 7), debes agregar la referencia al proyecto que quieres probar. Sin esa referencia no podrás importar la clase StringOperation ni acceder a sus métodos.

¿Cómo se escribe una prueba unitaria con xUnit paso a paso?

El patrón básico de una prueba unitaria sigue tres momentos: preparar el objeto, ejecutar la operación y verificar el resultado. En xUnit, marcar un método como prueba es tan simple como agregar el atributo [Fact] encima [06:30].

csharp using Xunit;

public class StringOperationTest { [Fact] public void ConcatenateStrings() { var strOperation = new StringOperation(); var result = strOperation.ConcatenateStrings("Hello", "Platzi"); Assert.Equal("Hello Platzi", result); } }

Fíjate en lo que está pasando ahí:

  1. Se instancia un objeto de la clase StringOperation con new.
  2. Se llama al método ConcatenateStrings pasando dos cadenas: "Hello" y "Platzi".
  3. Se compara el resultado contra el valor esperado usando Assert.Equal.

La clase Assert de xUnit es la que hace la comprobación real. El método Equal recibe dos argumentos: primero el valor esperado y segundo el valor actual que devuelve tu función. Si ambos coinciden, la prueba pasa.

¿Qué hace el atributo [Fact] en xUnit? Convierte un método común en una prueba unitaria que el runner puede detectar y ejecutar. Sin ese atributo, xUnit ignora el método.

¿Por qué la clase de prueba debe ser public? Porque el runner de xUnit solo puede acceder a clases públicas. Si la dejas como internal, las pruebas no se ejecutan aunque tengan el atributo [Fact].

¿Cómo ejecutar las pruebas desde el Test Explorer?

Visual Studio incluye una herramienta llamada Test Explorer que detecta automáticamente todas las pruebas dentro de la solución. Si no la ves, la activas desde View > Test Explorer [09:10].

Desde ahí puedes:

  • Ejecutar todas las pruebas del proyecto con un solo clic.
  • Correr una prueba individual seleccionándola y presionando Run.
  • Ver el resultado en verde si pasa o en rojo si falla.

Cuando la prueba aparece en verde, significa que el comportamiento del método coincide con lo que esperabas. Si cambias el valor esperado por algo distinto, por ejemplo agregando un espacio extra o un carácter, la prueba fallará. Ese es justamente el valor de las pruebas unitarias: detectar cuándo un cambio en el código rompe la lógica previa sin que tengas que revisar todo manualmente.

Y aquí viene lo interesante: una vez que tienes esta estructura montada, agregar más pruebas para otros métodos de StringOperation toma minutos. Solo repites el patrón arrange, act, assert y dejas que el Test Explorer haga el resto.

¿Tu primera prueba pasó en verde a la primera o tuviste que ajustar algo? Cuéntalo en los comentarios para que la comunidad aprenda de tu proceso.