Cosmos.EventSourcing.Testing.Utilities 0.0.4

dotnet add package Cosmos.EventSourcing.Testing.Utilities --version 0.0.4
                    
NuGet\Install-Package Cosmos.EventSourcing.Testing.Utilities -Version 0.0.4
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Cosmos.EventSourcing.Testing.Utilities" Version="0.0.4" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Cosmos.EventSourcing.Testing.Utilities" Version="0.0.4" />
                    
Directory.Packages.props
<PackageReference Include="Cosmos.EventSourcing.Testing.Utilities" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Cosmos.EventSourcing.Testing.Utilities --version 0.0.4
                    
#r "nuget: Cosmos.EventSourcing.Testing.Utilities, 0.0.4"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Cosmos.EventSourcing.Testing.Utilities@0.0.4
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Cosmos.EventSourcing.Testing.Utilities&version=0.0.4
                    
Install as a Cake Addin
#tool nuget:?package=Cosmos.EventSourcing.Testing.Utilities&version=0.0.4
                    
Install as a Cake Tool

Cosmos.EventSourcing.Testing.Utilities

NuGet

Utilidades para pruebas unitarias de command handlers en arquitecturas Event Sourcing para .NET 10.

Descripción

Este paquete provee clases abstractas para facilitar la creación de pruebas unitarias de command handlers en arquitecturas Event Sourcing, utilizando stores y senders en memoria (desconectadas de infraestructura real). Proporciona un framework de testing con sintaxis Given-When-Then para escribir tests claros y expresivos.

Instalación

dotnet add package Cosmos.EventSourcing.Testing.Utilities

Tipos de pruebas soportadas

Clase base Sincrónico Asincrónico Retorna datos
CommandHandlerTest<TCommand>
CommandHandlerTest<TCommand, TResult>
CommandHandlerAsyncTest<TCommand>
CommandHandlerAsyncTest<TCommand, TResult>

¿Cuándo usar cada clase?

¿Sincrónico o Asincrónico?

  • Command Handlers Sincrónicos: Son útiles cuando el handler no necesita consultar el event store para hidratar un aggregate root, es decir, cuando la lógica del comando no depende del estado previo del agregado (por ejemplo, simplemente emitir un evento sin validaciones sobre el estado actual).
  • Command Handlers Asincrónicos: Son recomendados cuando el handler sí necesita hidratar el aggregate root desde el event store, ya sea para realizar validaciones, cálculos, o cualquier proceso que requiera conocer el estado actual del agregado. También son útiles si el proceso de manejo del comando involucra operaciones asincrónicas.

1. CommandHandlerTest<TCommand>

  • Uso: Para command handlers SINCRÓNICOS que NO retornan datos (solo efectos colaterales, como eventos).
  • Ejemplo de uso:
    Pruebas de comandos que solo generan eventos, sin devolver un resultado.
public class CrearUsuarioTest : CommandHandlerTest<CrearUsuario>
{
    protected override ICommandHandler<CrearUsuario> Handler =>
        new CrearUsuarioHandler(eventStore);

    [Fact]
    public void Si_CreoUsuario_Debe_GenerarEvento()
    {
        // Given
        var comando = new CrearUsuario(_aggregateId);

        // When
        When(comando);

        // Then
        Then(new UsuarioCreado(_aggregateId));
    }
}

2. CommandHandlerTest<TCommand, TResult>

  • Uso: Para command handlers SINCRÓNICOS que RETORNAN un resultado (TResult).
  • Ejemplo de uso:
    Pruebas donde el comando retorna un valor, además de los efectos colaterales.
public class CalcularPrecioTest : CommandHandlerTest<CalcularPrecio, decimal>
{
    protected override ICommandHandler<CalcularPrecio, decimal> Handler =>
        new CalcularPrecioHandler(eventStore);

    [Fact]
    public void Si_CalculoPrecio_Debe_RetornarValor()
    {
        // Given
        var comando = new CalcularPrecio(_aggregateId);

        // When
        var resultado = When(comando);

        // Then
        resultado.Should().Be(100m);
        Then(new PrecioCalculado(_aggregateId, 100m));
    }
}

3. CommandHandlerAsyncTest<TCommand>

  • Uso: Para command handlers ASINCRÓNICOS que NO retornan datos (solo efectos colaterales).
  • Ejemplo de uso:
    Pruebas de comandos asíncronos que solo generan eventos.
public class CrearUsuarioAsyncTest : CommandHandlerAsyncTest<CrearUsuario>
{
    protected override ICommandHandlerAsync<CrearUsuario> Handler =>
        new CrearUsuarioHandler(eventStore);

    [Fact]
    public async Task Si_CreoUsuario_Debe_GenerarEvento()
    {
        // Given
        var comando = new CrearUsuario(_aggregateId);

        // When
        await WhenAsync(comando);

        // Then
        Then(new UsuarioCreado(_aggregateId));
    }
}

4. CommandHandlerAsyncTest<TCommand, TResult>

  • Uso: Para command handlers ASINCRÓNICOS que RETORNAN un resultado (TResult).
  • Ejemplo de uso:
    Pruebas donde el comando asíncrono retorna un valor, además de los efectos colaterales.
public class CalcularPrecioAsyncTest : CommandHandlerAsyncTest<CalcularPrecio, decimal>
{
    protected override ICommandHandlerAsync<CalcularPrecio, decimal> Handler =>
        new CalcularPrecioHandler(eventStore);

    [Fact]
    public async Task Si_CalculoPrecio_Debe_RetornarValor()
    {
        // Given
        var comando = new CalcularPrecio(_aggregateId);

        // When
        var resultado = await WhenAsync(comando);

        // Then
        resultado.Should().Be(100m);
        Then(new PrecioCalculado(_aggregateId, 100m));
    }
}

Criterios para elegir la clase base

  1. ¿El handler es sincrónico o asíncrono?

    • Si es asíncrono (Task o Task<TResult>): usa una de las variantes AsyncTest.
    • Si es sincrónico: usa una de las variantes Test.
  2. ¿El handler retorna un resultado?

    • Si retorna un valor (no void/Task): usa la variante con TResult.
    • Si no retorna valor: usa la variante sin TResult.

Notas adicionales

  • Usa los métodos Given, When/WhenAsync y Then para estructurar tus pruebas siguiendo el patrón Given-When-Then.
  • Puedes usar And para validar el estado de la raíz de agregado después de los eventos.
  • Los stores y senders son in-memory, ideales para pruebas unitarias rápidas y aisladas.

Requisitos

  • .NET 10.0 o superior

Dependencias

  • AwesomeAssertions (v9.3.0) - Librería de assertions fluidas
  • xUnit (v3.2.0) - Framework de testing
  • Cosmos.EventSourcing.Abstractions - Abstracciones de Event Sourcing
  • Cosmos.EventDriven.Abstractions - Abstracciones de EDA

Paquetes Relacionados

Licencia

Copyright © Cosmos. Todos los derechos reservados.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.0.4 192 12/3/2025
0.0.3 192 11/25/2025
0.0.1 235 9/19/2025