Nera.Lib.Test 2.0.0-dev0.4

This is a prerelease version of Nera.Lib.Test.
dotnet add package Nera.Lib.Test --version 2.0.0-dev0.4
                    
NuGet\Install-Package Nera.Lib.Test -Version 2.0.0-dev0.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="Nera.Lib.Test" Version="2.0.0-dev0.4" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Nera.Lib.Test" Version="2.0.0-dev0.4" />
                    
Directory.Packages.props
<PackageReference Include="Nera.Lib.Test" />
                    
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 Nera.Lib.Test --version 2.0.0-dev0.4
                    
#r "nuget: Nera.Lib.Test, 2.0.0-dev0.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 Nera.Lib.Test@2.0.0-dev0.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=Nera.Lib.Test&version=2.0.0-dev0.4&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Nera.Lib.Test&version=2.0.0-dev0.4&prerelease
                    
Install as a Cake Tool

Nera.Lib.Test

A comprehensive testing library for Nextera microservices architecture, providing utilities for unit tests, integration tests, and API response testing using the actual MethodResult structure with full support for error translation and .NET 2025 best practices.

πŸš€ Features

  • Base Test Classes: UnitTestBase, IntegrationTestBase, HandlerTestBase for consistent test patterns
  • MethodResult Testing: Full support for testing MethodResult and VoidMethodResult responses
  • Error Translation: Built-in support for English and Vietnamese error messages
  • FluentAssertions Extensions: Custom assertions for MethodResult validation with localization
  • Test Data Builders: Bogus-based builders for generating realistic test data
  • Entity Builders: Fluent builders for User, Organization, Role, Permission entities
  • Integration Testing: Complete WebApplicationFactory setup with authentication and localization
  • HTTP Client Helpers: Easy HTTP request testing with MethodResult support
  • gRPC Testing: Helpers for testing gRPC services and clients
  • MediatR Testing: Helpers for testing Commands, Queries, and Handlers
  • Time Testing: FakeClock for testing time-dependent code
  • Test Attributes: [UnitTest], [IntegrationTest], [EndToEndTest] for categorization
  • Database Testing: In-memory and Testcontainers support
  • Multi-tenant Support: Built-in support for testing multi-tenant scenarios
  • Repository Mocking: Fluent builder for IRepository mocks
  • Caching Testing: Mock helpers for IDistributedCache and IMemoryCache
  • Messaging Testing: MassTransit ConsumeContext, IBus, and message capture
  • SignalR Testing: Hub context mocking and message capture
  • Validation Testing: FluentValidation test extensions
  • Domain Event Testing: Event capture and verification
  • Specification Testing: Specification pattern test helpers
  • .NET 9 Ready: Updated for latest .NET framework with modern patterns

πŸ“¦ Installation

Reference this project in your test projects:

<ItemGroup>
    <ProjectReference Include="..\..\BuildingBlocks\Nera.Lib.Test\Nera.Lib.Test.csproj" />
</ItemGroup>

πŸ”§ Quick Start

1. Unit Testing with Base Class

[UnitTest]
public class MyServiceTests : UnitTestBase
{
    [Fact]
    public void MyMethod_ShouldWork()
    {
        // Use built-in helpers
        var mock = CreateMock<IMyDependency>();
        var data = Create<MyEntity>();
        
        // Your test logic
    }
}

2. Handler Testing

[UnitTest("Handlers")]
public class CreateUserCommandHandlerTests : HandlerTestBase<CreateUserCommandHandler, CreateUserCommand, UserDto>
{
    private Mock<IUserRepository> _userRepository = null!;

    protected override CreateUserCommandHandler CreateHandler()
    {
        _userRepository = CreateMock<IUserRepository>();
        return new CreateUserCommandHandler(_userRepository.Object);
    }

    protected override CreateUserCommand CreateValidRequest()
    {
        return new CreateUserCommand { Email = "test@example.com" };
    }

    [Fact]
    public async Task Handle_ValidRequest_ReturnsUser()
    {
        var result = await ExecuteWithValidRequestAsync();
        result.Should().NotBeNull();
    }
}

3. Integration Testing

[IntegrationTest]
public class UserControllerTests : IntegrationTestBase<Program>
{
    public UserControllerTests(CustomWebApplicationFactory<Program> factory) 
        : base(factory) { }

    [Fact]
    public async Task GetUsers_ReturnsSuccess()
    {
        var client = GetAuthenticatedClient();
        var response = await client.GetAsync("/users");
        response.EnsureSuccessStatusCode();
    }
}

4. Entity Builders

// Build test users with fluent API
var user = UserTestDataBuilder.Create()
    .WithEmail("john@example.com")
    .WithOrgId(orgId)
    .Active()
    .Build();

var users = UserTestDataBuilder.Create()
    .WithOrgId(orgId)
    .Build(10);

// Build organizations
var org = OrganizationTestDataBuilder.Create()
    .WithName("Test Corp")
    .WithDomain("test.com")
    .Active()
    .Build();

// Build roles
var role = RoleTestDataBuilder.Create()
    .WithCode("ADMIN")
    .WithOrgId(orgId)
    .AsSystemRole()
    .Build();

5. MediatR Testing Helpers

var mediator = MediatRTestHelpers.CreateMediatorMock();

// Setup response
mediator.SetupSend<GetUserQuery, UserDto>(expectedUser);

// Verify calls
mediator.VerifySend<GetUserQuery, UserDto>(Times.Once());

6. gRPC Testing

// Create test context
var context = GrpcTestHelpers.CreateServerCallContext(
    method: "/UserService/GetUser",
    requestHeaders: GrpcTestHelpers.CreateTestMetadata(orgId: "org-1")
);

// Create async call responses
var response = GrpcTestHelpers.CreateAsyncUnaryCall(expectedResponse);

7. Time Testing

var clock = new FakeClock(new DateTime(2024, 1, 1));

// Use in tests
var service = new MyService(clock);

// Advance time
clock.AdvanceByDays(7);
clock.AdvanceByHours(2);

8. Basic MethodResult Testing

[Fact]
public void CreateUser_Success_ShouldReturnMethodResult()
{
    // Arrange
    var userData = TestDataBuilders.User.Generate();

    // Act
    var result = MethodResultTestHelpers.CreateSuccess(userData);

    // Assert
    result.Should().BeSuccess()
        .And.HaveTraceId()
        .And.HaveMessage("Success");
        
    result.Data.Should().Be(userData);
}

9. Localized Error Testing

[Fact]
public void CreateUser_ValidationError_ShouldReturnLocalizedError()
{
    // Act
    var result = MethodResultTestHelpers.CreateLocalizedError<UserTestData>(
        "VALIDATION_ERROR",
        "ValidationError",
        "Error occurred",
        language: "vi");

    // Assert
    result.Should().BeFailure()
        .And.HaveLocalizedErrorMessage("VALIDATION_ERROR", "ValidationError", "vi");
}

10. Paginated Response Testing

[Fact]
public void GetUsers_Paginated_ShouldReturnCorrectPagination()
{
    // Arrange
    var users = TestDataBuilders.User.Generate(15);
    
    // Act
    var result = MethodResultTestHelpers.CreateSuccessPaginated(
        users.Take(10), 
        page: 1, 
        pageSize: 10, 
        total: 15);

    // Assert
    result.Should().BeSuccess()
        .And.HavePagination(1, 10, 15);
}

11. Integration Testing with Localization

public class UserControllerIntegrationTests : IClassFixture<CustomWebApplicationFactory<Program>>
{
    private readonly HttpClient _client;

    public UserControllerIntegrationTests(CustomWebApplicationFactory<Program> factory)
    {
        _client = factory.CreateAuthenticatedClientWithLanguage("test-user", "test-org", "vi");
    }

    [Fact]
    public async Task CreateUser_ValidRequest_ShouldReturnSuccess()
    {
        // Arrange
        var request = new CreateUserRequest 
        { 
            Email = "test@example.com",
            FirstName = "Test",
            LastName = "User"
        };

        // Act
        var result = await _client.PostAsync<CreateUserResponse>("/users", request);

        // Assert
        result.Should().BeSuccess();
    }
}

πŸ“š Components

MethodResultTestHelpers

Create test MethodResult instances easily:

// Success with data
var result = MethodResultTestHelpers.CreateSuccess(data);

// Success paginated
var paginatedResult = MethodResultTestHelpers.CreateSuccessPaginated(
    items, page, pageSize, total);

// Void success
var voidResult = MethodResultTestHelpers.CreateSuccessVoid();

// Error
var errorResult = MethodResultTestHelpers.CreateError<T>(
    "ERROR_CODE", "Error message");

// Localized error
var localizedError = MethodResultTestHelpers.CreateLocalizedError<T>(
    "ERROR_CODE", "ErrorKey", "Default message", language: "vi");

FluentAssertions Extensions

Rich assertions for MethodResult validation with localization:

result.Should().BeSuccess();
result.Should().BeFailure();
result.Should().HaveData(expectedData);
result.Should().HaveDataThat(data => data.Id != Guid.Empty);
result.Should().HaveMessage("Expected message");
result.Should().HaveLocalizedMessage("MessageKey", "vi");
result.Should().HaveErrorCode("ERROR_CODE");
result.Should().HaveLocalizedErrorMessage("ERROR_CODE", "ErrorKey", "vi");
result.Should().HavePagination();
result.Should().HavePagination(page, pageSize, total);
result.Should().HaveTraceId();
result.Should().HaveProcessingTime();

Test Data Builders

Generate realistic test data using Bogus:

// Users
var user = TestDataBuilders.User.Generate();
var specificUser = TestDataBuilders.User.WithEmail("test@example.com");
var users = TestDataBuilders.User.Generate(10);

// Organizations
var org = TestDataBuilders.Organization.Generate();
var activeOrg = TestDataBuilders.Organization.Active();
var orgWithDomain = TestDataBuilders.Organization.WithDomain("example.com");

// Pagination
var pagination = TestDataBuilders.Pagination.Create(1, 10);
var searchPagination = TestDataBuilders.Pagination.WithSearch("test", 1, 10);

// Errors
var error = TestDataBuilders.Error.Generate();
var validationError = TestDataBuilders.Error.Validation();
var notFoundError = TestDataBuilders.Error.NotFound();

// HTTP Requests
var request = TestDataBuilders.HttpRequest.Generate();
var postRequest = TestDataBuilders.HttpRequest.Post();

CustomWebApplicationFactory

Complete integration testing setup with localization:

public class IntegrationTestBase : IClassFixture<CustomWebApplicationFactory<Program>>
{
    protected readonly CustomWebApplicationFactory<Program> Factory;
    protected readonly HttpClient Client;

    public IntegrationTestBase(CustomWebApplicationFactory<Program> factory)
    {
        Factory = factory;
        Client = factory.CreateAuthenticatedClient();
    }
}

// With custom authentication
var adminClient = factory.CreateClientWithClaims(
    new Claim("userId", "admin-user"),
    new Claim("role", "Admin")
);

// With language preference
var vietnameseClient = factory.CreateAuthenticatedClientWithLanguage(
    "test-user", "test-org", "vi");

// With database seeding
await factory.SeedDatabaseAsync<TestDbContext>(async context =>
{
    context.Users.Add(testUser);
    await context.SaveChangesAsync();
});

// With service mocking
var mockService = new Mock<IExternalService>();
var factory = new CustomWebApplicationFactory<Program>()
    .WithMockedService(mockService.Object);

HttpClientTestHelpers

Easy HTTP request testing with MethodResult support:

// Basic HTTP methods
var result = await client.GetAsync<UserTestData>("/users/{id}");
var result = await client.PostAsync<UserTestData>("/users", userData);
var result = await client.PutAsync<UserTestData>("/users/{id}", userData);
var result = await client.DeleteAsync<UserTestData>("/users/{id}");

// Void operations
var result = await client.PostVoidAsync("/users/{id}/activate");
var result = await client.PutVoidAsync("/users/{id}", userData);
var result = await client.DeleteVoidAsync("/users/{id}");

// Custom headers
var result = await client.SendWithHeadersAsync<UserTestData>(
    HttpMethod.Get,
    "/users/{id}",
    headers: new Dictionary<string, string>
    {
        ["X-Custom-Header"] = "value",
        ["Accept-Language"] = "vi"
    });

πŸ—οΈ Project Structure

Nera.Lib.Test/
β”œβ”€β”€ Assertions/                      # FluentAssertions extensions
β”‚   └── MethodResultAssertions.cs    # Custom assertions for MethodResult
β”œβ”€β”€ Attributes/                      # Test categorization attributes
β”‚   └── TestCategoryAttributes.cs    # [UnitTest], [IntegrationTest], etc.
β”œβ”€β”€ Base/                            # Base test classes
β”‚   β”œβ”€β”€ UnitTestBase.cs              # Base for unit tests
β”‚   β”œβ”€β”€ HandlerTestBase.cs           # Base for MediatR handlers
β”‚   └── IntegrationTestBase.cs       # Base for integration tests
β”œβ”€β”€ Builders/                        # Test data builders (Bogus)
β”‚   β”œβ”€β”€ EntityBuilders.cs            # Fluent entity builders
β”‚   └── TestDataModels.cs            # Test data POCOs
β”œβ”€β”€ Examples/                        # Example usage tests
β”‚   └── ExampleTests.cs              # Comprehensive examples
β”œβ”€β”€ Extensions/                      # Extension methods
β”‚   └── TestExtensions.cs            # General test extensions
β”œβ”€β”€ Fixtures/                        # Integration test fixtures
β”‚   └── CustomWebApplicationFactory.cs  # WebApplicationFactory setup
β”œβ”€β”€ Helpers/                         # Test helper classes
β”‚   β”œβ”€β”€ CachingTestHelpers.cs        # IDistributedCache/IMemoryCache mocks
β”‚   β”œβ”€β”€ CommonTestDataBuilders.cs    # Common test data generators
β”‚   β”œβ”€β”€ DatabaseTestHelpers.cs       # In-memory DbContext helpers
β”‚   β”œβ”€β”€ DomainEventTestHelpers.cs    # Domain event capture/verify
β”‚   β”œβ”€β”€ GrpcTestHelpers.cs           # gRPC testing utilities
β”‚   β”œβ”€β”€ HttpClientTestHelpers.cs     # HTTP client extensions
β”‚   β”œβ”€β”€ MessagingTestHelpers.cs      # MassTransit mock helpers
β”‚   β”œβ”€β”€ MethodResultTestHelpers.cs   # MethodResult creation helpers
β”‚   β”œβ”€β”€ MultiTenantTestHelpers.cs    # Multi-tenant context helpers
β”‚   β”œβ”€β”€ RepositoryMockHelpers.cs     # IRepository mock builder
β”‚   β”œβ”€β”€ SignalRTestHelpers.cs        # SignalR hub mock helpers
β”‚   β”œβ”€β”€ SpecificationTestHelpers.cs  # Specification pattern tests
β”‚   β”œβ”€β”€ TestServiceHelpers.cs        # Service mock helpers
β”‚   └── ValidationTestHelpers.cs     # FluentValidation test helpers
β”œβ”€β”€ Models/                          # Test data models
β”‚   └── TestDataModels.cs            # POCOs for testing
β”œβ”€β”€ GlobalUsing.cs                   # Global imports
β”œβ”€β”€ Nera.Lib.Test.csproj             # Project file
└── README.md                        # This file

πŸ§ͺ Test Categories

Unit Tests (75%)

[Fact]
public void UserEntity_Init_ShouldCreateValidUser()
{
    // Test domain logic, business rules, validators
}

Integration Tests (20%)

[Fact]
public async Task UserAPI_CreateUser_ShouldPersistToDatabase()
{
    // Test full API flow with database
}

Contract Tests (5%)

[Fact]
public void UserResponse_Schema_ShouldMatchContract()
{
    // Test API contract adherence
}

πŸ“‹ API Response Structure

The library supports your exact API response format:

{
    "status": "Success",
    "message": "Success", 
    "data": [...],
    "_metadata": {
        "traceId": "TEST12345:0001",
        "processingTime": 0,
        "timestamp": "2025-01-21T10:00:00.000Z",
        "pagination": {
            "page": 1,
            "pageSize": 10,
            "count": 10,
            "total": 100,
            "totalPages": 10,
            "hasPreviousPage": false,
            "hasNextPage": true
        }
    }
}

🌐 Localization Support

Error Message Translation

The library supports automatic error message translation:

// English (default)
var englishError = MethodResultTestHelpers.CreateLocalizedError<UserTestData>(
    "VALIDATION_ERROR", "ValidationError", language: "en");
// Message: "Validation error"

// Vietnamese
var vietnameseError = MethodResultTestHelpers.CreateLocalizedError<UserTestData>(
    "VALIDATION_ERROR", "ValidationError", language: "vi");
// Message: "Lα»—i xΓ‘c thα»±c dα»― liệu"

HTTP Client with Language Support

// Create client with Vietnamese language preference
var client = factory.CreateAuthenticatedClientWithLanguage("user", "org", "vi");

// Send request - error messages will be in Vietnamese
var result = await client.PostAsync<UserTestData>("/users", userData);

🎯 Best Practices

1. Use Specific Assertions

// Good - Specific assertions with localization
result.Should().BeSuccess()
    .And.HavePagination(1, 10, 100)
    .And.HaveDataThat(users => users.All(u => u.IsActive))
    .And.HaveLocalizedMessage("SuccessMessage", "vi");

// ❌ Avoid - Generic assertions
Assert.True(result.Status == "Success");

2. Use Test Data Builders

// Good - Consistent test data
var user = TestDataBuilders.User.WithEmail("test@example.com");

// ❌ Avoid - Manual test data creation
var user = new UserTestData { Id = Guid.NewGuid(), Email = "test@example.com", ... };

3. Test Real API Responses

// Good - Test actual MethodResult structure
var result = await client.GetAsync<UserTestData>("/users/{id}");
result.Should().BeSuccess();

// ❌ Avoid - Testing DTOs directly
var users = await response.Content.ReadFromJsonAsync<IEnumerable<UserTestData>>();

4. Use Authentication in Integration Tests

// Good - Authenticated tests
var client = factory.CreateAuthenticatedClient("user123", "org456");

// ❌ Avoid - Anonymous tests for protected endpoints
var client = factory.CreateClient();

5. Test Localization

// Good - Test both languages
[Theory]
[InlineData("en")]
[InlineData("vi")]
public async Task CreateUser_ShouldReturnLocalizedMessage(string language)
{
    var client = factory.CreateAuthenticatedClientWithLanguage("user", "org", language);
    var result = await client.PostAsync<UserTestData>("/users", userData);
    
    result.Should().HaveLocalizedMessage("SuccessMessage", language);
}

πŸ”— Integration with Nextera

This library is specifically designed for Nextera's architecture:

  • MethodResult Support: Matches your exact API response structure
  • Multi-tenant Testing: Built-in OrgId support
  • Authentication: Test authentication handler with claims
  • Clean Architecture: Supports testing all layers
  • CQRS Pattern: Works with MediatR commands/queries
  • Error Translation: Supports English and Vietnamese error messages
  • Middleware Integration: Works with your global exception handling

πŸ“ Examples

See Examples/ExampleTests.cs for comprehensive usage examples covering:

  • MethodResult testing
  • Localized error testing
  • Pagination testing
  • Integration testing
  • Test data generation
  • Authentication testing
  • HTTP client testing

🀝 Contributing

When adding new test utilities:

  1. Follow the existing patterns
  2. Add comprehensive XML documentation
  3. Include usage examples
  4. Ensure .NET 9 compatibility
  5. Test with actual Nextera APIs
  6. Support both English and Vietnamese localization

πŸ“¦ Helper Categories

Database Testing (DatabaseTestHelpers)

// Create in-memory database context
var context = DatabaseTestHelpers.CreateInMemoryContext<MyDbContext>();

// Seed test data
await DatabaseTestHelpers.SeedDataAsync(context, entity1, entity2);

// Clear all data
await DatabaseTestHelpers.ClearAllDataAsync(context);

// Shared context for multiple tests
using var shared = DatabaseTestHelpers.CreateSharedContext<MyDbContext>();
var ctx = shared.GetContext();

Validation Testing (ValidationTestHelpers)

// Test validator success
await validator.ShouldBeValidAsync(validRequest);

// Test validator failure
await validator.ShouldHaveValidationErrorForAsync(invalidRequest, x => x.Email);

// Test specific error code
await validator.ShouldHaveValidationErrorWithCodeAsync(request, "NotEmpty");

// Fluent assertions for ValidationResult
var result = await validator.ValidateAsync(request);
result.Should()
    .BeInvalid()
    .And.HaveErrorForProperty("Email")
    .And.HaveErrorCount(2);

Caching Testing (CachingTestHelpers)

// Create in-memory distributed cache
var cache = CachingTestHelpers.CreateInMemoryDistributedCache();

// Create mock distributed cache
var mockCache = CachingTestHelpers.CreateDistributedCacheMock();

// Verify cache operations
mockCache.VerifyCacheSet("my-key", Times.Once());
mockCache.VerifyCacheGet("my-key", Times.Exactly(2));

Messaging Testing (MessagingTestHelpers)

// Create consume context
var context = MessagingTestHelpers.CreateConsumeContext(myMessage);

// Create mock bus
var busMock = MessagingTestHelpers.CreateBusMock();

// Capture published messages
var capture = busMock.CapturePublished<MyEvent>();
await service.DoSomething();
capture.ShouldHaveMessage();

// Test consumer
var result = await MessagingTestHelpers.TestConsumerAsync(consumer, message);
result.ShouldBeSuccessful();

SignalR Testing (SignalRTestHelpers)

// Create mock hub context
var hubContext = SignalRTestHelpers.CreateHubContextMock<MyHub>();

// Capture messages
var capture = hubContext.CaptureMessages();
await service.NotifyClients();
capture.ShouldHaveMethod("ReceiveNotification");

// Verify operations
hubContext.VerifySentToAll("MethodName", Times.Once());
hubContext.VerifyAddedToGroup("conn-1", "group-name", Times.Once());

Repository Testing (RepositoryMockHelpers)

// Create repository mock with builder
var mockBuilder = RepositoryMockHelpers.CreateGenericRepositoryMock<MyEntity>()
    .WithEntities(entity1, entity2)
    .WithGetById(id => entities.FirstOrDefault(e => e.Id == id));
var repo = mockBuilder.Build();

// Verify operations
mockBuilder.AddedEntities.Should().HaveCount(1);
repo.VerifyAdd(Times.Once());

Domain Event Testing (DomainEventTestHelpers)

// Create event capture
var capture = DomainEventTestHelpers.CreateEventCapture();

// Add events
capture.Add(new UserCreatedEvent());

// Verify events
capture.ShouldHaveEvent<UserCreatedEvent>();
capture.ShouldHaveCountOf<UserCreatedEvent>(1);

Specification Testing (SpecificationTestHelpers)

// Test specification matching
Expression<Func<User, bool>> spec = u => u.IsActive && u.Age > 18;
spec.ShouldMatch(activeAdultUser);
spec.ShouldNotMatch(inactiveUser);

// Combine specifications
var combinedSpec = spec1.And(spec2);
var orSpec = spec1.Or(spec2);
var notSpec = spec1.Not();

// Test against collection
var testUsers = new[] { user1, user2, user3 };
spec.Should(testUsers).MatchExactly(2);

Multi-Tenant Testing (MultiTenantTestHelpers)

// Create multi-tenant test data
var testData = MultiTenantTestHelpers.CreateTestData(orgCount: 3, entitiesPerOrg: 10);
var org1 = testData.FirstOrg;
var org2 = testData.SecondOrg;

// Create tenant context
var tenantContext = MultiTenantTestHelpers.CreateTenantContext(orgId, "user-1")
    .WithRole("Admin")
    .WithPermissions("users.read", "users.write");

// Assert tenant isolation
entities.ShouldAllBelongToOrg(expectedOrgId, e => e.OrgId);
entities.ShouldNotContainOrgData(excludedOrgId, e => e.OrgId);

πŸ”„ CustomWebApplicationFactory

The CustomWebApplicationFactory provides a complete integration testing setup with support for authentication, database isolation, and service mocking.

Basic Usage

public class MyIntegrationTests : IClassFixture<CustomWebApplicationFactory<Program>>
{
    private readonly CustomWebApplicationFactory<Program> _factory;

    public MyIntegrationTests(CustomWebApplicationFactory<Program> factory)
    {
        _factory = factory;
    }

    [Fact]
    public async Task GetUsers_ReturnsSuccess()
    {
        // Create authenticated client
        var client = _factory.CreateAuthenticatedClient();
        
        // Make request
        var result = await client.GetAsync<List<UserDto>>("/users");
        
        // Assert
        result.Should().BeSuccess();
    }
}

Fluent Configuration

// Configure with custom database name
var factory = new CustomWebApplicationFactory<Program>()
    .WithDatabaseName("TestDb_MyTests");

// Configure with additional services
var factory = new CustomWebApplicationFactory<Program>()
    .WithServices(services =>
    {
        services.AddSingleton<IMyService>(mockService.Object);
    });

// Chain configurations
var factory = new CustomWebApplicationFactory<Program>()
    .WithDatabaseName("TestDb")
    .WithServices(services => services.AddSingleton(mock.Object));

Authentication Helpers

// Basic authenticated client
var client = factory.CreateAuthenticatedClient();

// With specific user/org
var client = factory.CreateAuthenticatedClient("user-123", "org-456");

// With language preference
var client = factory.CreateAuthenticatedClientWithLanguage("user", "org", "vi");

// With custom claims
var client = factory.CreateClientWithClaims(
    new Claim("userId", "admin"),
    new Claim("role", "SuperAdmin"),
    new Claim("permission", "users.manage")
);

Database Seeding

// Seed data before tests
await factory.SeedDatabaseAsync<MyDbContext>(async context =>
{
    context.Users.AddRange(testUsers);
    context.Organizations.Add(testOrg);
    await context.SaveChangesAsync();
});

// Clear data after tests
await factory.ClearDatabaseAsync<MyDbContext>();

πŸ“Š Helper Categories Summary

Helper Namespace Purpose
DatabaseTestHelpers Nera.Lib.Test.Helpers In-memory DbContext, seeding, clearing
ValidationTestHelpers Nera.Lib.Test.Helpers FluentValidation testing extensions
CachingTestHelpers Nera.Lib.Test.Helpers IDistributedCache/IMemoryCache mocks
MessagingTestHelpers Nera.Lib.Test.Helpers MassTransit ConsumeContext, IBus mocks
RepositoryMockHelpers Nera.Lib.Test.Helpers IRepository mock builder with fluent API
DomainEventTestHelpers Nera.Lib.Test.Helpers Domain event capture and verification
SpecificationTestHelpers Nera.Lib.Test.Helpers Specification pattern testing
MultiTenantTestHelpers Nera.Lib.Test.Helpers Multi-tenant context and isolation
SignalRTestHelpers Nera.Lib.Test.Helpers SignalR hub mocking and message capture
GrpcTestHelpers Nera.Lib.Test.Helpers gRPC service testing utilities
HttpClientTestHelpers Nera.Lib.Test.Helpers HTTP client extensions for MethodResult
MethodResultTestHelpers Nera.Lib.Test.Helpers Create test MethodResult instances
TestServiceHelpers Nera.Lib.Test.Helpers Generic service and logger mocks
CommonTestDataBuilders Nera.Lib.Test.Helpers Bogus-based test data generators

🧩 Package Dependencies

<ItemGroup>
    <PackageReference Include="AutoFixture" Version="4.18.1"/>
    <PackageReference Include="Bogus" Version="35.6.4"/>
    <PackageReference Include="FluentAssertions" Version="8.7.1"/>
    <PackageReference Include="Grpc.Core.Api" Version="2.67.0"/>
    <PackageReference Include="MassTransit" Version="8.5.6"/>
    <PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="9.0.9"/>
    <PackageReference Include="Microsoft.AspNetCore.SignalR" Version="1.1.0"/>
    <PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="9.0.9"/>
    <PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="9.0.9"/>
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0"/>
    <PackageReference Include="Moq" Version="4.20.72"/>
    <PackageReference Include="Testcontainers" Version="4.7.0"/>
    <PackageReference Include="xunit" Version="2.9.3"/>
</ItemGroup>

πŸ“„ License

This library is part of the Nextera project and follows the same licensing terms.

Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  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
2.0.0-dev0.4 37 3/4/2026
2.0.0-dev0.2 57 3/2/2026
2.0.0-dev0.1 40 3/2/2026
1.0.10 85 3/2/2026
1.0.1 135 1/5/2026
1.0.0 457 9/12/2025