test: add FluentValidation tests for command and query validators

Add tests verifying that FluentValidation integrates correctly with
the CQRS discovery and handler registration pipeline.

🤖 Generated with [Claude Code](https://claude.ai/claude-code)

Co-Authored-By: Svrnty Inc. <eng@svrnty.com>
This commit is contained in:
Svrnty 2026-02-28 17:36:34 -05:00
parent 2ff8eae75c
commit acde9ec22a
2 changed files with 188 additions and 0 deletions

View File

@ -0,0 +1,184 @@
using FluentValidation;
using Microsoft.Extensions.DependencyInjection;
using Svrnty.CQRS.Abstractions;
using Svrnty.CQRS.Abstractions.Discovery;
namespace Svrnty.CQRS.Tests;
// Validator for CreatePersonCommand
public class CreatePersonCommandValidator : AbstractValidator<CreatePersonCommand>
{
public CreatePersonCommandValidator()
{
RuleFor(x => x.FirstName).NotEmpty().WithMessage("FirstName is required");
RuleFor(x => x.LastName).NotEmpty().WithMessage("LastName is required");
}
}
// Validator for PersonQuery
public class PersonQueryValidator : AbstractValidator<PersonQuery>
{
public PersonQueryValidator()
{
RuleFor(x => x.NameFilter).MaximumLength(100).WithMessage("NameFilter too long");
}
}
public class FluentValidationTests
{
[Fact]
public void AddCommand_WithValidator_RegistersHandlerAndValidator()
{
var services = new ServiceCollection();
Svrnty.CQRS.FluentValidation.ServiceCollectionExtensions
.AddCommand<CreatePersonCommand, CreatePersonCommandHandler, CreatePersonCommandValidator>(services);
var provider = services.BuildServiceProvider();
var handler = provider.GetService<ICommandHandler<CreatePersonCommand>>();
var validator = provider.GetService<IValidator<CreatePersonCommand>>();
Assert.NotNull(handler);
Assert.NotNull(validator);
Assert.IsType<CreatePersonCommandHandler>(handler);
Assert.IsType<CreatePersonCommandValidator>(validator);
}
[Fact]
public void AddCommand_WithResultAndValidator_RegistersHandlerAndValidator()
{
var services = new ServiceCollection();
Svrnty.CQRS.FluentValidation.ServiceCollectionExtensions
.AddCommand<CreatePersonCommand, CreatePersonResult, CreatePersonCommandHandler, CreatePersonCommandValidator>(services);
var provider = services.BuildServiceProvider();
var handler = provider.GetService<ICommandHandler<CreatePersonCommand, CreatePersonResult>>();
var validator = provider.GetService<IValidator<CreatePersonCommand>>();
Assert.NotNull(handler);
Assert.NotNull(validator);
}
[Fact]
public void AddCommand_WithResultAndValidator_RegistersCommandMeta()
{
var services = new ServiceCollection();
Svrnty.CQRS.FluentValidation.ServiceCollectionExtensions
.AddCommand<CreatePersonCommand, CreatePersonResult, CreatePersonCommandHandler, CreatePersonCommandValidator>(services);
var provider = services.BuildServiceProvider();
var metas = provider.GetServices<ICommandMeta>().ToList();
Assert.Single(metas);
Assert.Equal(typeof(CreatePersonCommand), metas[0].CommandType);
Assert.Equal(typeof(CreatePersonResult), metas[0].CommandResultType);
}
[Fact]
public void AddQuery_WithValidator_RegistersHandlerAndValidator()
{
var services = new ServiceCollection();
Svrnty.CQRS.FluentValidation.ServiceCollectionExtensions
.AddQuery<PersonQuery, IEnumerable<string>, PersonQueryHandler, PersonQueryValidator>(services);
var provider = services.BuildServiceProvider();
var handler = provider.GetService<IQueryHandler<PersonQuery, IEnumerable<string>>>();
var validator = provider.GetService<IValidator<PersonQuery>>();
Assert.NotNull(handler);
Assert.NotNull(validator);
Assert.IsType<PersonQueryHandler>(handler);
Assert.IsType<PersonQueryValidator>(validator);
}
[Fact]
public async Task Validator_RejectsInvalidCommand()
{
var validator = new CreatePersonCommandValidator();
var command = new CreatePersonCommand { FirstName = "", LastName = "" };
var result = await validator.ValidateAsync(command);
Assert.False(result.IsValid);
Assert.Equal(2, result.Errors.Count);
}
[Fact]
public async Task Validator_AcceptsValidCommand()
{
var validator = new CreatePersonCommandValidator();
var command = new CreatePersonCommand { FirstName = "John", LastName = "Doe" };
var result = await validator.ValidateAsync(command);
Assert.True(result.IsValid);
Assert.Empty(result.Errors);
}
[Fact]
public async Task Validator_ResolvedFromDI_WorksCorrectly()
{
var services = new ServiceCollection();
Svrnty.CQRS.FluentValidation.ServiceCollectionExtensions
.AddCommand<CreatePersonCommand, CreatePersonCommandHandler, CreatePersonCommandValidator>(services);
var provider = services.BuildServiceProvider();
var validator = provider.GetRequiredService<IValidator<CreatePersonCommand>>();
var invalidResult = await validator.ValidateAsync(new CreatePersonCommand { FirstName = "", LastName = "" });
Assert.False(invalidResult.IsValid);
var validResult = await validator.ValidateAsync(new CreatePersonCommand { FirstName = "Jane", LastName = "Doe" });
Assert.True(validResult.IsValid);
}
[Fact]
public void CqrsBuilder_AddCommand_WithValidator_RegistersBoth()
{
var services = new ServiceCollection();
services.AddSvrntyCqrs(builder =>
{
Svrnty.CQRS.FluentValidation.CqrsBuilderExtensions
.AddCommand<CreatePersonCommand, CreatePersonCommandHandler, CreatePersonCommandValidator>(builder);
});
var provider = services.BuildServiceProvider();
Assert.NotNull(provider.GetService<ICommandHandler<CreatePersonCommand>>());
Assert.NotNull(provider.GetService<IValidator<CreatePersonCommand>>());
}
[Fact]
public void CqrsBuilder_AddCommand_WithResultAndValidator_RegistersBoth()
{
var services = new ServiceCollection();
services.AddSvrntyCqrs(builder =>
{
Svrnty.CQRS.FluentValidation.CqrsBuilderExtensions
.AddCommand<CreatePersonCommand, CreatePersonResult, CreatePersonCommandHandler, CreatePersonCommandValidator>(builder);
});
var provider = services.BuildServiceProvider();
Assert.NotNull(provider.GetService<ICommandHandler<CreatePersonCommand, CreatePersonResult>>());
Assert.NotNull(provider.GetService<IValidator<CreatePersonCommand>>());
}
[Fact]
public void CqrsBuilder_AddQuery_WithValidator_RegistersBoth()
{
var services = new ServiceCollection();
services.AddSvrntyCqrs(builder =>
{
Svrnty.CQRS.FluentValidation.CqrsBuilderExtensions
.AddQuery<PersonQuery, IEnumerable<string>, PersonQueryHandler, PersonQueryValidator>(builder);
});
var provider = services.BuildServiceProvider();
Assert.NotNull(provider.GetService<IQueryHandler<PersonQuery, IEnumerable<string>>>());
Assert.NotNull(provider.GetService<IValidator<PersonQuery>>());
}
}

View File

@ -16,11 +16,15 @@
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="10.0.0-*" />
<PackageReference Include="FluentValidation" Version="11.11.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Svrnty.CQRS\Svrnty.CQRS.csproj" />
<ProjectReference Include="..\..\Svrnty.CQRS.Abstractions\Svrnty.CQRS.Abstractions.csproj" />
<ProjectReference Include="..\..\Svrnty.CQRS.FluentValidation\Svrnty.CQRS.FluentValidation.csproj" />
<ProjectReference Include="..\..\Svrnty.CQRS.DynamicQuery\Svrnty.CQRS.DynamicQuery.csproj" />
<ProjectReference Include="..\..\Svrnty.CQRS.DynamicQuery.Abstractions\Svrnty.CQRS.DynamicQuery.Abstractions.csproj" />
</ItemGroup>
</Project>