Trellis.Testing
3.0.0-alpha.127
See the version list below for details.
dotnet add package Trellis.Testing --version 3.0.0-alpha.127
NuGet\Install-Package Trellis.Testing -Version 3.0.0-alpha.127
<PackageReference Include="Trellis.Testing" Version="3.0.0-alpha.127" />
<PackageVersion Include="Trellis.Testing" Version="3.0.0-alpha.127" />
<PackageReference Include="Trellis.Testing" />
paket add Trellis.Testing --version 3.0.0-alpha.127
#r "nuget: Trellis.Testing, 3.0.0-alpha.127"
#:package Trellis.Testing@3.0.0-alpha.127
#addin nuget:?package=Trellis.Testing&version=3.0.0-alpha.127&prerelease
#tool nuget:?package=Trellis.Testing&version=3.0.0-alpha.127&prerelease
Testing Utilities
FluentAssertions extensions, test builders, and fake implementations for testing Railway Oriented Programming patterns with Trellis.
Installation
dotnet add package Trellis.Testing
Quick Start
Result Assertions
using Trellis.Testing;
// Success
result.Should().BeSuccess()
.Which.Value.Should().Be(expected);
// Failure by type
result.Should().BeFailureOfType<NotFoundError>()
.Which.Should().HaveDetail("User not found");
Validation Error Assertions
result.Should()
.BeFailureOfType<ValidationError>()
.Which.Should()
.HaveFieldCount(3)
.And.HaveFieldError("firstName")
.And.HaveFieldError("email")
.And.HaveFieldErrorWithDetail("age", "Must be 18 or older");
Maybe Assertions
maybe.Should().HaveValue().Which.Should().Be("hello");
maybe.Should().BeNone();
Test Builders
using Trellis.Testing.Builders;
// Quick Result creation
var result = ResultBuilder.NotFound<User>("User not found");
// Complex validation errors
var error = ValidationErrorBuilder.Create()
.WithFieldError("email", "Email is required")
.WithFieldError("age", "Must be 18 or older")
.Build();
Fake Repository
using Trellis.Testing.Fakes;
var repo = new FakeRepository<User, UserId>();
var sut = new UserService(repo);
var result = await sut.CreateUserAsync(command, CancellationToken.None);
result.Should().BeSuccess();
repo.Exists(result.Value.Id).Should().BeTrue();
repo.PublishedEvents.Should().ContainSingle()
.Which.Should().BeOfType<UserCreatedEvent>();
TestActorProvider — Scoped Actor Switching
Eliminates try/finally boilerplate in authorization tests. WithActor temporarily switches the actor and restores the previous one on dispose.
using Trellis.Testing.Fakes;
var actorProvider = new TestActorProvider("admin", "Orders.Read", "Orders.Write");
// Temporarily switch to a restricted user
await using var scope = actorProvider.WithActor("user-1", "Orders.Read");
var result = await mediator.Send(new CreateOrderCommand());
result.Should().BeFailure();
// scope disposes → actor reverts to admin
ReplaceResourceLoader — DI Registration Replacement
Replaces existing IResourceLoader<TCommand, TResource> registrations in one call — no manual RemoveAll needed. Registered as scoped, matching the production lifetime.
using Trellis.Testing;
// Stateless fake — capture a pre-created instance
var fakeLoader = new FakeOrderResourceLoader(fakeRepo);
builder.ConfigureServices(services =>
{
services.ReplaceResourceLoader<CancelOrderCommand, Order>(_ => fakeLoader);
});
// Scoped dependency — resolve from the container
builder.ConfigureServices(services =>
{
services.ReplaceResourceLoader<CancelOrderCommand, Order>(
sp => new FakeOrderResourceLoader(sp.GetRequiredService<AppDbContext>()));
});
CreateClientWithActor — Integration Test HttpClient
Creates an HttpClient with the X-Test-Actor header pre-set for authorization integration tests.
using Trellis.Testing;
var client = _factory.CreateClientWithActor("user-1", "Orders.Create", "Orders.Read");
var response = await client.PostAsync("/api/orders", content);
Assertion API Reference
Result
| Method | Description |
|---|---|
BeSuccess() |
Assert result is success |
BeFailure() |
Assert result is failure |
BeFailureOfType<TError>() |
Assert failure with specific error type |
HaveValue(expected) |
Assert success value equals expected |
HaveValueMatching(predicate) |
Assert success value satisfies predicate |
HaveValueEquivalentTo(expected) |
Assert success value using structural comparison |
HaveErrorCode(code) |
Assert failure has specific error code |
HaveErrorDetail(detail) |
Assert failure has specific error detail |
HaveErrorDetailContaining(substring) |
Assert failure error detail contains substring |
Async variants (BeSuccessAsync, BeFailureAsync, BeFailureOfTypeAsync) are available for Task<Result<T>> and ValueTask<Result<T>>.
Error
| Method | Description |
|---|---|
Be(expected) |
Assert error equals expected (by Code) |
HaveCode(code) |
Assert error code |
HaveDetail(detail) |
Assert error detail message |
HaveDetailContaining(substring) |
Assert error detail contains substring |
HaveInstance(instance) |
Assert error instance identifier |
BeOfType<TError>() |
Assert error is of a specific type |
ValidationError
| Method | Description |
|---|---|
HaveFieldError(fieldName) |
Assert field has error |
HaveFieldErrorWithDetail(field, detail) |
Assert field has specific error |
HaveFieldCount(count) |
Assert number of field errors |
Maybe
| Method | Description |
|---|---|
HaveValue() |
Assert Maybe has a value |
BeNone() |
Assert Maybe has no value |
HaveValueEqualTo(expected) |
Assert value equals expected |
HaveValueMatching(predicate) |
Assert value satisfies predicate |
HaveValueEquivalentTo(expected) |
Assert value using structural comparison |
Before & After
| Before | After |
|---|---|
result.IsSuccess.Should().BeTrue() |
result.Should().BeSuccess() |
result.Error.Should().BeOfType<NotFoundError>() |
result.Should().BeFailureOfType<NotFoundError>() |
maybe.HasValue.Should().BeTrue() |
maybe.Should().HaveValue() |
Related Packages
- Trellis.Results — Core
Result<T>andMaybe<T>types - Trellis.DomainDrivenDesign — DDD building blocks
- Trellis.Authorization —
Actor,IActorProvider, authorization primitives
License
MIT — see LICENSE for details.
| Product | Versions 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. |
-
net10.0
- FluentAssertions (>= 6.12.1)
- Microsoft.AspNetCore.Mvc.Testing (>= 10.0.5)
- Trellis.Authorization (>= 3.0.0-alpha.127)
- Trellis.DomainDrivenDesign (>= 3.0.0-alpha.127)
- Trellis.Results (>= 3.0.0-alpha.127)
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 |
|---|---|---|
| 3.0.0-alpha.135 | 22 | 3/26/2026 |
| 3.0.0-alpha.127 | 45 | 3/23/2026 |
| 3.0.0-alpha.123 | 47 | 3/19/2026 |
| 3.0.0-alpha.118 | 52 | 3/14/2026 |
| 3.0.0-alpha.111 | 46 | 3/12/2026 |
| 3.0.0-alpha.104 | 62 | 3/9/2026 |
| 3.0.0-alpha.100 | 41 | 3/4/2026 |
| 3.0.0-alpha.99 | 41 | 3/4/2026 |
| 3.0.0-alpha.98 | 39 | 3/3/2026 |
| 3.0.0-alpha.95 | 43 | 3/2/2026 |
| 3.0.0-alpha.94 | 47 | 3/2/2026 |
| 3.0.0-alpha.93 | 47 | 3/1/2026 |
| 3.0.0-alpha.92 | 56 | 2/28/2026 |
| 3.0.0-alpha.83 | 44 | 2/27/2026 |