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
<PackageReference Include="Nera.Lib.Test" Version="1.0.0" />
<PackageVersion Include="Nera.Lib.Test" Version="1.0.0" />
<PackageReference Include="Nera.Lib.Test" />
paket add Nera.Lib.Test --version 1.0.0
#r "nuget: Nera.Lib.Test, 1.0.0"
#:package Nera.Lib.Test@1.0.0
#addin nuget:?package=Nera.Lib.Test&version=1.0.0
#tool nuget:?package=Nera.Lib.Test&version=1.0.0
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:
- Follow the existing patterns
- Add comprehensive XML documentation
- Include usage examples
- Ensure .NET 9 compatibility
- Test with actual Nextera APIs
- Support both English and Vietnamese localization
π License
This library is part of the Nextera project and follows the same licensing terms.
Product | Versions 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. |
-
net9.0
- AutoFixture (>= 4.18.1)
- Bogus (>= 35.6.3)
- FluentAssertions (>= 6.12.0)
- Microsoft.AspNetCore.Mvc.Testing (>= 9.0.8)
- Microsoft.EntityFrameworkCore.InMemory (>= 9.0.8)
- Microsoft.Extensions.Localization (>= 9.0.8)
- Moq (>= 4.20.72)
- Nera.Lib.Core (>= 1.0.8)
- Nera.Lib.Database (>= 1.0.1)
- Nera.Lib.Domain (>= 1.0.5)
- Nera.Lib.Web (>= 1.0.5)
- Testcontainers (>= 4.7.0)
- xunit (>= 2.9.3)
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 |