0

Microsoft Orleans #17: Unit Testing

En esta clase aprenderemos cómo hacer pruebas unitarias en Orleans, utilizando herramientas como Orleans Test Kit, xUnit y Moq para simular y validar el comportamiento de los Granos.

Objetivos de la Clase

  • Implementar pruebas unitarias para Granos Orleans.
  • Usar Orleans Test Kit para pruebas locales sin un Silo Orleans real.
  • Aplicar Mocking con Moq para aislar dependencias en Granos.
  • Ejecutar pruebas con xUnit para validar el funcionamiento de Orleans.

¿Por qué Hacer Pruebas Unitarias en Orleans?

Las pruebas unitarias son fundamentales para garantizar que los Granos Orleans funcionan correctamente sin necesidad de iniciar un Silo Orleans real. Esto permite:

  • Detectar errores rápidamente, sin necesidad de levantar toda la infraestructura.
  • Asegurar que las funciones del Grano se comporten según lo esperado.
  • Reducir el tiempo de ejecución de pruebas, ya que no se requiere un clúster Orleans en ejecución.

Configurar un Proyecto de Pruebas para Orleans

1. Crear un Proyecto de Pruebas

Ejecuta en la terminal:

dotnet new xunit -n OrleansTests
cd OrleansTests
dotnet add package Orleans.TestingHost
dotnet add package Moq
dotnet add package Microsoft.Extensions.DependencyInjection
dotnet add reference ../OrleansDemo/OrleansDemo.csproj

Esto crea un proyecto de pruebas xUnit y añade las dependencias necesarias para probar Orleans.

Pruebas Unitarias con Orleans Test Kit

Orleans Test Kit permite probar Granos sin necesidad de iniciar un Silo Orleans real.

1. Crear una Prueba para un Grano Simple

Supongamos que tenemos el siguiente Grano:

public interface IContadorGrain : IGrainWithGuidKey
{
    Task Incrementar();
    Task<int> ObtenerValor();
}
public class ContadorGrain : Grain, IContadorGrain
{
    private int _valor;

    public Task Incrementar()
    {
        _valor++;
        return Task.CompletedTask;
    }

    public Task<int> ObtenerValor()
    {
        return Task.FromResult(_valor);
    }
}

2. Crear una Prueba con Orleans Test Kit

Crea ContadorGrainTests.cs en OrleansTests:

csharpCopiarEditarusing System;
using System.Threading.Tasks;
using Orleans.TestKit;
using Xunit;

public class ContadorGrainTests : TestKitBase
{
    [Fact]
    public async Task Incrementar_Deberia_Aumentar_Valor()
    {
        var grain = Silo.CreateGrain<ContadorGrain>(Guid.NewGuid());

        await grain.Incrementar();
        var valor = await grain.ObtenerValor();

        Assert.Equal(1, valor);
    }
}

Explicación del Código

  • TestKitBase: Simula un Silo Orleans en memoria para pruebas.
  • Silo.CreateGrain<>(): Crea una instancia del Grano sin necesidad de Orleans real.
  • Assert.Equal(1, valor): Verifica que el contador aumentó correctamente.

Pruebas con Mocking usando Moq

Si un Grano depende de otro, podemos simular Granos Orleans usando Moq.

1. Definir un Grano que Dependa de Otro

public interface IClienteGrain : IGrainWithStringKey
{
    Task<string> ObtenerNombre();
}

public interface IOrdenGrain : IGrainWithGuidKey
{
    Task<string> ProcesarOrden(string clienteId);
}
public class OrdenGrain : Grain, IOrdenGrain
{
    public async Task<string> ProcesarOrden(string clienteId)
    {
        var cliente = GrainFactory.GetGrain<IClienteGrain>(clienteId);
        var nombre = await cliente.ObtenerNombre();
        return $"Orden procesada para {nombre}";
    }
}

2. Crear una Prueba con Moq

Crea OrdenGrainTests.cs en OrleansTests:

using System.Threading.Tasks;
using Moq;
using Orleans;
using Orleans.TestKit;
using Xunit;

public class OrdenGrainTests : TestKitBase
{
    [Fact]
    public async Task ProcesarOrden_Deberia_Devolver_Nombre_Cliente()
    {
        var clienteMock = new Mock<IClienteGrain>();
        clienteMock.Setup(x => x.ObtenerNombre()).ReturnsAsync("Carlos");

        Silo.AddGrain(clienteMock.Object);

        var ordenGrain = Silo.CreateGrain<OrdenGrain>(Guid.NewGuid());
        var resultado = await ordenGrain.ProcesarOrden("cliente123");

        Assert.Equal("Orden procesada para Carlos", resultado);
    }
}

Explicación del Código

  • Moq simula IClienteGrain y devuelve "Carlos" al llamarlo.
  • Silo.AddGrain(clienteMock.Object) registra el Grano simulado en el entorno de prueba.
  • El Grano OrdenGrain usa el Grano simulado sin ejecutar Orleans real.

Ejecutar las Pruebas

Ejecuta en la terminal:

dotnet test

Si todo está configurado correctamente, las pruebas deberían pasar sin errores.


Cuestionario de Autoevaluación

  1. ¿Qué es Orleans Test Kit y para qué se usa en las pruebas unitarias?
  2. ¿Cómo se crean pruebas unitarias para Granos en Orleans sin levantar un Silo real?
  3. ¿Qué ventaja ofrece Moq para simular Granos Orleans en pruebas unitarias?
  4. ¿Cómo se usa Silo.CreateGrain<>() en una prueba Orleans?
  5. ¿Qué sucede si un Grano depende de otro Grano en una prueba unitaria?

Resumen de la Clase

  • Orleans Test Kit permite probar Granos sin necesidad de un Silo real.
  • Implementamos pruebas unitarias para validar el comportamiento de los Granos.
  • Moq permite simular dependencias de Granos, facilitando pruebas aisladas.
  • Ejecutamos las pruebas con xUnit y verificamos que los Granos Orleans funcionen correctamente.

Próxima Clase: Optimización de Performance

En la siguiente clase, aprenderemos cómo mejorar el rendimiento de Orleans, reduciendo latencias y optimizando el uso de memoria.

Fernando Sonego

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *