xUnit

This guide provides complete examples for testing FlexBase applications using xUnit, FluentAssertions, and InMemory EF Core.

Prerequisites

NuGet Packages

Add these packages to your test projects:

<ItemGroup>
  <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.x" />
  <PackageReference Include="xunit" Version="2.x" />
  <PackageReference Include="xunit.runner.visualstudio" Version="2.x" />
  <PackageReference Include="FluentAssertions" Version="6.x" />
  <PackageReference Include="Moq" Version="4.x" />
  <PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="9.x" />
</ItemGroup>

Part 1: Domain Model Tests

Domain model tests verify pure business logic without any database dependencies. They use FlexHostMock to create domain model instances with proper dependency injection.

Setting Up FlexHostMockFixture

Create a shared fixture to configure FlexHostMock with AutoMapper and domain model registrations:

Writing Domain Model Tests


Part 2: PreBus Validation Tests

PreBus validation tests verify your business rule plugins. These tests use InMemoryRepoFactory to provide a real (but in-memory) database with seed data.

Setting Up InMemoryRepoFactory

Create an InMemory repository factory that uses EF Core's InMemory provider:

Setting Up Seed Data

Create seed data classes that are applied when the InMemory database is created:

Writing Validation Tests

Testing SlugUnique Validation


Part 3: Query Tests

Query tests verify that your read operations correctly fetch data from the database. They use InMemory EF Core with seed data.

Setting Up QueryTestFixture

Writing Query Tests


Part 4: Handler Tests (Optional)

Handler tests verify the orchestration logic in command handlers. These are optional because domain model + validation tests often provide sufficient coverage.


Best Practices Summary

✅ Do

  1. Use unique database names per test class:

  2. Implement IDisposable to clean up resources:

  3. Use xUnit collection fixtures for expensive setup:

  4. Leverage seed data for realistic test scenarios:

  5. Use FluentAssertions for readable assertions:

  6. Test edge cases (null, empty, whitespace):

❌ Don't

  1. Don't share mutable state between tests without isolation

  2. Don't rely on test execution order

  3. Don't use magic strings - define constants or use seed data

  4. Don't test FlexBase internals - focus on your business logic

  5. Don't over-mock - use real InMemory database when possible


Troubleshooting

Common Issues

Issue: Tests fail with "Entity type 'X' was not found" Solution: Ensure your ApplicationEFInMemoryDbContext includes all entity DbSets

Issue: Seed data not found during tests Solution: Verify OnModelCreating calls your seed data methods

Issue: Tests interfere with each other Solution: Use unique database names with Guid.NewGuid()

Issue: AutoMapper configuration errors Solution: Register all required mapper profiles in the fixture


Reference: FlexBase Testing APIs

API
Purpose

FlexHostMock

Test-friendly IFlexHost implementation

flexHost.GetDomainModel<T>()

Gets domain model instance with DI

packet.Dto = dto

Assigns DTO to data packet

packet.HasError

Boolean - check if validation failed

packet.Errors()

Returns FlexErrorDictionary

packet.AddError(key, msg)

Adds validation error

dto.SetAppContext(ctx)

Sets application context

dto.SetGeneratedId(id)

Sets pre-generated entity ID

dto.GetAppContext()

Gets application context

dto.GetGeneratedId()

Gets pre-generated entity ID

Last updated