# Application tests — CQRS handlers & validators

In a generated extension the CQRS **handler is a thin delegator** to `I{E}Service`
(`Create{E}CommandHandler(I{E}Service service) => _service.CreateAsync(...)`). The logic
+ EF access live in the **service** — test it separately (see backend-services.md).

Tests go to `Tests/{Module}/Application/`.

## Handler tests — mock the service, Verify the delegation

- Inject `Mock<I{E}Service>` (a class field). No DbContext at this level.
- `[Fact]` per handler. Pass `TestContext.Current.CancellationToken`.
- Verify in the Assert block: `_serviceMock.Verify(s => s.XxxAsync(...), Times.Once)`.

```csharp
using Xunit;
using FluentAssertions;
using Moq;
using MyApp.Application.Orders.Commands;
using MyApp.Application.Orders.Handlers;
using MyApp.Application.Orders.Interfaces;

namespace MyApp.Tests.Orders.Application;

[Trait("Category", "Business")]
[Trait("Type", "Unit")]
public class OrderHandlersTests
{
    private readonly Mock<IOrderService> _serviceMock = new();

    #region CreateOrderCommandHandler

    [Fact]
    public async Task Handle_ValidCommand_DelegatesToServiceCreate()
    {
        var command = new CreateOrderCommand("ORD-001", 100m);
        var expectedId = Guid.NewGuid();
        _serviceMock
            .Setup(s => s.CreateAsync(It.IsAny<CreateOrderCommand>(), It.IsAny<CancellationToken>()))
            .ReturnsAsync(expectedId);
        var handler = new CreateOrderCommandHandler(_serviceMock.Object);

        var result = await handler.Handle(command, TestContext.Current.CancellationToken);

        result.Should().Be(expectedId);
        _serviceMock.Verify(s => s.CreateAsync(command, It.IsAny<CancellationToken>()), Times.Once);
    }

    #endregion
}
```

## Validator tests — FluentValidation.TestHelper

One `[Fact]` per required field + one per business rule.

```csharp
using FluentValidation.TestHelper;

[Fact]
public void Validate_EmptyCode_Fails()
{
    var command = new CreateOrderCommand(null!, 100m);

    _validator.TestValidate(command).ShouldHaveValidationErrorFor(x => x.Code);
}
```

## Anti-patterns

- ❌ Mocking `ICoreDbContext`/`IExtensionsDbContext` in the HANDLER test — the handler
  doesn't touch the DbContext; mock `I{E}Service`.
- ❌ `Verify(...)` inside the Act block — always in Assert.
- ❌ `CancellationToken.None` — `TestContext.Current.CancellationToken`.
- ❌ `[Theory]` per handler — one `[Fact]` per scenario.
