Cómo probar una API ASP.NET Core con xUnit y Moq

Cómo probar una API ASP.NET Core con xUnit y Moq, 3000 carcateres

Las pruebas automatizadas son una parte esencial del desarrollo de software moderno. En una API ASP.NET Core no basta con que el código compile; también es importante garantizar que cada cambio no rompa funcionalidades existentes. Para ello, xUnit y Moq forman una de las combinaciones más utilizadas en el ecosistema .NET para crear pruebas unitarias rápidas, confiables y fáciles de mantener.

En este artículo aprenderás cómo probar una API ASP.NET Core utilizando estas herramientas y conocerás las mejores prácticas para escribir pruebas que realmente aporten valor.

¿Qué es xUnit?

xUnit es uno de los frameworks de pruebas unitarias más populares para .NET. Es el sucesor de NUnit y está diseñado para ofrecer una sintaxis sencilla, ejecución rápida y una excelente integración con Visual Studio, Rider y Azure DevOps.

Entre sus principales ventajas destacan:

  • Fácil integración con proyectos .NET.
  • Excelente rendimiento.
  • Compatible con .NET moderno.
  • Gran soporte para pruebas paralelas.
  • Amplia comunidad.

Una prueba en xUnit normalmente utiliza el atributo:

[Fact]
public void MiPrueba()
{
    Assert.True(true);
}

Cuando la prueba se ejecuta, xUnit verifica que todas las condiciones (Assert) sean correctas.


¿Qué es Moq?

Mientras xUnit ejecuta las pruebas, Moq permite crear objetos simulados (Mocks) para reemplazar dependencias reales.

Por ejemplo, un controlador normalmente depende de un servicio:

public class ProductsController
{
    private readonly IProductService _service;

    public ProductsController(IProductService service)
    {
        _service = service;
    }
}

En una prueba unitaria no queremos acceder a una base de datos real.

Con Moq podemos simular el comportamiento del servicio.

var mockService = new Mock<IProductService>();

mockService
    .Setup(x => x.GetAll())
    .Returns(new List<Product>
    {
        new Product { Id = 1, Name = "Laptop" }
    });

De esta manera la prueba se ejecuta de forma completamente aislada.


Instalación

En el proyecto de pruebas instala los paquetes necesarios:

dotnet add package xunit
dotnet add package xunit.runner.visualstudio
dotnet add package Moq
dotnet add package Microsoft.NET.Test.Sdk

Con esto ya podrás ejecutar pruebas desde Visual Studio o mediante la consola.


Creando una prueba del controlador

Supongamos el siguiente controlador:

[ApiController]
[Route("api/products")]
public class ProductsController : ControllerBase
{
    private readonly IProductService _service;

    public ProductsController(IProductService service)
    {
        _service = service;
    }

    [HttpGet]
    public IActionResult Get()
    {
        var products = _service.GetAll();
        return Ok(products);
    }
}

Ahora escribimos la prueba.

public class ProductsControllerTests
{
    [Fact]
    public void Get_Returns_OkResult()
    {
        var mockService = new Mock<IProductService>();

        mockService.Setup(x => x.GetAll())
                   .Returns(new List<Product>());

        var controller = new ProductsController(mockService.Object);

        var result = controller.Get();

        Assert.IsType<OkObjectResult>(result);
    }
}

La prueba verifica que el método devuelve un 200 OK.


Verificando el contenido

También podemos comprobar que la información retornada es correcta.

[Fact]
public void Get_Returns_Product_List()
{
    var products = new List<Product>
    {
        new Product
        {
            Id = 1,
            Name = "Mouse"
        }
    };

    var mock = new Mock<IProductService>();

    mock.Setup(x => x.GetAll())
        .Returns(products);

    var controller = new ProductsController(mock.Object);

    var result = controller.Get() as OkObjectResult;

    var data = Assert.IsAssignableFrom<List<Product>>(result.Value);

    Assert.Single(data);
    Assert.Equal("Mouse", data[0].Name);
}

Con esto validamos tanto el código HTTP como la información enviada al cliente.


Verificando llamadas

Moq también permite comprobar que un método fue ejecutado.

mock.Verify(x => x.GetAll(), Times.Once);

Esto asegura que el controlador realmente llamó al servicio exactamente una vez.


Probando excepciones

Las APIs deben manejar errores correctamente.

mock.Setup(x => x.GetAll())
.Throws(new Exception());

Posteriormente se verifica que el controlador responda adecuadamente según la lógica implementada.


Buenas prácticas

Para obtener pruebas mantenibles sigue estas recomendaciones:

  • Cada prueba debe validar un único comportamiento.
  • Usa nombres descriptivos para identificar rápidamente qué se está probando.
  • Evita depender de bases de datos o servicios externos en pruebas unitarias.
  • Simula únicamente las dependencias necesarias con Moq.
  • Mantén las pruebas pequeñas y rápidas para ejecutarlas con frecuencia.
  • Agrupa las pruebas por controlador o servicio para facilitar su mantenimiento.
  • Ejecuta las pruebas automáticamente en tu pipeline de integración continua.

Pruebas unitarias vs pruebas de integración

Es importante diferenciar ambos enfoques:

Pruebas unitarias

  • Ejecutan una sola clase.
  • Simulan dependencias.
  • Son muy rápidas.
  • Detectan errores de lógica.

Pruebas de integración

  • Ejecutan varios componentes juntos.
  • Utilizan la configuración real de la aplicación.
  • Verifican rutas, middleware, autenticación y acceso a datos.
  • Son más lentas, pero validan el funcionamiento completo de la API.

Lo recomendable es combinar ambos tipos para lograr una cobertura equilibrada.

Implementar pruebas unitarias con xUnit y Moq es una de las mejores prácticas para desarrollar APIs robustas en ASP.NET Core. Mientras xUnit proporciona una estructura clara para crear y ejecutar pruebas, Moq facilita el aislamiento de las dependencias mediante objetos simulados, permitiendo validar la lógica de negocio sin necesidad de conectarse a bases de datos o servicios externos.

Adoptar estas herramientas desde las primeras etapas del desarrollo mejora la calidad del código, reduce errores en producción y hace que las refactorizaciones sean mucho más seguras. En proyectos empresariales, contar con una buena suite de pruebas no solo incrementa la confianza del equipo, sino que también acelera el ciclo de desarrollo y despliegue continuo.

Te puede interesar...

Deja un comentario