Nera.Lib.Test 1.0.0

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

  • 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
  • Integration Testing: Complete WebApplicationFactory setup with authentication and localization
  • HTTP Client Helpers: Easy HTTP request testing with MethodResult support
  • API Response Helpers: Easy creation of test responses matching your API structure
  • Database Testing: In-memory and Testcontainers support
  • Multi-tenant Support: Built-in support for testing multi-tenant scenarios
  • .NET 9 Ready: Updated for latest .NET framework with modern patterns

πŸ“¦ Installation

Reference this project in your test projects:

<ItemGroup>
    <ProjectReference Include="..\..\nera-library\Nera.Lib.Test\Nera.Lib.Test.csproj" />
</ItemGroup>

πŸ”§ Quick Start

1. 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);
}

2. 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");
}

3. 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);
}

4. 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>("/api/v1/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>("/api/v1/users/{id}");
var result = await client.PostAsync<UserTestData>("/api/v1/users", userData);
var result = await client.PutAsync<UserTestData>("/api/v1/users/{id}", userData);
var result = await client.DeleteAsync<UserTestData>("/api/v1/users/{id}");

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

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

πŸ—οΈ Project Structure

Nera.Lib.Test/
β”œβ”€β”€ Assertions/           # FluentAssertions extensions
β”œβ”€β”€ Builders/            # Test data builders (Bogus)
β”œβ”€β”€ Examples/            # Example usage tests
β”œβ”€β”€ Fixtures/            # Integration test fixtures
β”œβ”€β”€ Helpers/             # MethodResult and HTTP helpers
β”œβ”€β”€ Models/              # Test data models
β”œβ”€β”€ GlobalUsing.cs       # Global imports
└── 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>("/api/v1/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>("/api/v1/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>("/api/v1/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

πŸ“„ 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
1.0.0 64 9/12/2025