AstreCode.Backend.Shared.UnitTest
9.0.0
See the version list below for details.
dotnet add package AstreCode.Backend.Shared.UnitTest --version 9.0.0
NuGet\Install-Package AstreCode.Backend.Shared.UnitTest -Version 9.0.0
<PackageReference Include="AstreCode.Backend.Shared.UnitTest" Version="9.0.0" />
<PackageVersion Include="AstreCode.Backend.Shared.UnitTest" Version="9.0.0" />
<PackageReference Include="AstreCode.Backend.Shared.UnitTest" />
paket add AstreCode.Backend.Shared.UnitTest --version 9.0.0
#r "nuget: AstreCode.Backend.Shared.UnitTest, 9.0.0"
#:package AstreCode.Backend.Shared.UnitTest@9.0.0
#addin nuget:?package=AstreCode.Backend.Shared.UnitTest&version=9.0.0
#tool nuget:?package=AstreCode.Backend.Shared.UnitTest&version=9.0.0
AstreCode.Backend.Shared.UnitTest
Testing utilities and base classes for AstreCode microservices.
Description
The AstreCode.Backend.Shared.UnitTest package provides essential testing utilities and base classes for building comprehensive test suites for .NET 8.0 backend services. This package includes test service base classes, mocking utilities, and testing helpers.
Installation
To install this package, use the .NET CLI:
dotnet add package AstreCode.Backend.Shared.UnitTest
Or via Package Manager Console:
Install-Package AstreCode.Backend.Shared.UnitTest
Features
๐งช Test Service Base Classes
- ApplicationTestService: Base class for application service testing
- UnitTestService: Base class for unit testing with common utilities
- Test Data Builders: Helper classes for creating test data
- Mock Setup Utilities: Common mocking patterns and setups
๐ง Testing Utilities
- Mock Management: Centralized mock object management
- Test Data Factories: Factory patterns for test data creation
- Assertion Helpers: Custom assertion methods and extensions
- Test Configuration: Test-specific configuration helpers
๐ Mocking Framework Integration
- NSubstitute Integration: Pre-configured NSubstitute mocking
- Mock Factories: Factory methods for common mock objects
- Mock Verification: Helper methods for mock verification
- Test Doubles: Stub and mock implementations
๐๏ธ Test Infrastructure
- Test Base Classes: Common test infrastructure
- Setup and Teardown: Standardized test lifecycle management
- Test Isolation: Proper test isolation and cleanup
- Performance Testing: Basic performance testing utilities
Example Usage
Application Service Testing
using Shared.UnitTest;
using NSubstitute;
using Xunit;
public class UserServiceTests : ApplicationTestService
{
private readonly IUserService _userService;
private readonly IUserRepository _userRepository;
public UserServiceTests()
{
_userRepository = Substitute.For<IUserRepository>();
_userService = new UserService(_userRepository, Mapper, Localizer, EncryptionService, UnitOfWork, CurrentUser);
}
[Fact]
public async Task CreateUserAsync_ValidData_ReturnsUserDto()
{
// Arrange
var createUserDto = new CreateUserDto
{
FirstName = "John",
LastName = "Doe",
Email = "john.doe@example.com"
};
var user = new User
{
Id = Guid.NewGuid(),
FirstName = createUserDto.FirstName,
LastName = createUserDto.LastName,
Email = createUserDto.Email
};
_userRepository.AddAsync(Arg.Any<User>()).Returns(user);
// Act
var result = await _userService.CreateUserAsync(createUserDto);
// Assert
Assert.NotNull(result);
Assert.Equal(createUserDto.FirstName, result.FirstName);
Assert.Equal(createUserDto.LastName, result.LastName);
Assert.Equal(createUserDto.Email, result.Email);
await _userRepository.Received(1).AddAsync(Arg.Any<User>());
}
[Fact]
public async Task GetUserAsync_UserExists_ReturnsUserDto()
{
// Arrange
var userId = Guid.NewGuid();
var user = new User
{
Id = userId,
FirstName = "John",
LastName = "Doe",
Email = "john.doe@example.com"
};
_userRepository.GetByIdAsync(userId).Returns(user);
// Act
var result = await _userService.GetUserAsync(userId);
// Assert
Assert.NotNull(result);
Assert.Equal(userId, result.Id);
Assert.Equal("John", result.FirstName);
}
[Fact]
public async Task GetUserAsync_UserNotFound_ThrowsNotFoundException()
{
// Arrange
var userId = Guid.NewGuid();
_userRepository.GetByIdAsync(userId).Returns((User)null);
// Act & Assert
await Assert.ThrowsAsync<NotFoundException>(() => _userService.GetUserAsync(userId));
}
}
Unit Test Service Usage
using Shared.UnitTest;
using NSubstitute;
using Xunit;
public class EmailServiceTests : UnitTestService
{
private readonly IEmailService _emailService;
public EmailServiceTests()
{
_emailService = new EmailService();
}
[Theory]
[InlineData("test@example.com", true)]
[InlineData("invalid-email", false)]
[InlineData("", false)]
[InlineData(null, false)]
public void IsValidEmail_ValidatesEmailCorrectly(string email, bool expected)
{
// Act
var result = _emailService.IsValidEmail(email);
// Assert
Assert.Equal(expected, result);
}
[Fact]
public void SendEmailAsync_ValidEmail_SendsSuccessfully()
{
// Arrange
var emailDto = new EmailDto
{
To = "test@example.com",
Subject = "Test Subject",
Body = "Test Body"
};
// Act
var result = _emailService.SendEmailAsync(emailDto);
// Assert
Assert.NotNull(result);
Assert.True(result.IsCompletedSuccessfully);
}
}
Test Data Builders
using Shared.UnitTest;
public class UserTestDataBuilder
{
private User _user = new User();
public UserTestDataBuilder WithId(Guid id)
{
_user.Id = id;
return this;
}
public UserTestDataBuilder WithName(string firstName, string lastName)
{
_user.FirstName = firstName;
_user.LastName = lastName;
return this;
}
public UserTestDataBuilder WithEmail(string email)
{
_user.Email = email;
return this;
}
public UserTestDataBuilder WithStatus(UserStatus status)
{
_user.Status = status;
return this;
}
public User Build()
{
return _user;
}
public static UserTestDataBuilder Create() => new UserTestDataBuilder();
}
// Usage in tests
[Fact]
public async Task UpdateUserAsync_ValidData_UpdatesUser()
{
// Arrange
var user = UserTestDataBuilder.Create()
.WithId(Guid.NewGuid())
.WithName("John", "Doe")
.WithEmail("john.doe@example.com")
.WithStatus(UserStatus.Active)
.Build();
var updateDto = new UpdateUserDto
{
FirstName = "Jane",
LastName = "Smith"
};
_userRepository.GetByIdAsync(user.Id).Returns(user);
// Act
var result = await _userService.UpdateUserAsync(user.Id, updateDto);
// Assert
Assert.Equal("Jane", result.FirstName);
Assert.Equal("Smith", result.LastName);
}
Mock Setup Utilities
using Shared.UnitTest;
using NSubstitute;
public class OrderServiceTests : ApplicationTestService
{
private readonly IOrderService _orderService;
private readonly IOrderRepository _orderRepository;
private readonly IUserRepository _userRepository;
public OrderServiceTests()
{
_orderRepository = Substitute.For<IOrderRepository>();
_userRepository = Substitute.For<IUserRepository>();
_orderService = new OrderService(
_orderRepository,
_userRepository,
Mapper,
Localizer,
EncryptionService,
UnitOfWork,
CurrentUser
);
}
[Fact]
public async Task CreateOrderAsync_ValidData_CreatesOrder()
{
// Arrange
var userId = Guid.NewGuid();
var user = UserTestDataBuilder.Create()
.WithId(userId)
.WithStatus(UserStatus.Active)
.Build();
var createOrderDto = new CreateOrderDto
{
CustomerId = userId,
Items = new List<OrderItemDto>
{
new OrderItemDto { ProductId = Guid.NewGuid(), Quantity = 2 }
}
};
SetupMocks(user, createOrderDto);
// Act
var result = await _orderService.CreateOrderAsync(createOrderDto);
// Assert
Assert.NotNull(result);
await _orderRepository.Received(1).AddAsync(Arg.Any<Order>());
await _userRepository.Received(1).GetByIdAsync(userId);
}
private void SetupMocks(User user, CreateOrderDto createOrderDto)
{
_userRepository.GetByIdAsync(user.Id).Returns(user);
_orderRepository.AddAsync(Arg.Any<Order>()).Returns(new Order { Id = Guid.NewGuid() });
}
}
Performance Testing
using Shared.UnitTest;
using System.Diagnostics;
public class PerformanceTests : UnitTestService
{
[Fact]
public async Task ProcessLargeDataset_PerformanceTest()
{
// Arrange
var largeDataset = GenerateLargeDataset(10000);
var service = new DataProcessingService();
// Act
var stopwatch = Stopwatch.StartNew();
var result = await service.ProcessDataAsync(largeDataset);
stopwatch.Stop();
// Assert
Assert.NotNull(result);
Assert.True(stopwatch.ElapsedMilliseconds < 5000,
$"Processing took {stopwatch.ElapsedMilliseconds}ms, expected less than 5000ms");
}
private List<DataItem> GenerateLargeDataset(int count)
{
return Enumerable.Range(1, count)
.Select(i => new DataItem { Id = i, Value = $"Item {i}" })
.ToList();
}
}
Configuration
Test Project Setup
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="xunit" Version="2.6.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.3" />
<PackageReference Include="coverlet.collector" Version="6.0.0" />
<PackageReference Include="AstreCode.Backend.Shared.UnitTest" Version="8.0.0" />
</ItemGroup>
</Project>
Test Configuration
// In your test setup
public class TestStartup
{
public void ConfigureServices(IServiceCollection services)
{
// Configure test services
services.AddScoped<IUserRepository, MockUserRepository>();
services.AddScoped<IOrderRepository, MockOrderRepository>();
// Configure AutoMapper for tests
services.AddAutoMapper(typeof(TestMappingProfile));
}
}
Dependencies
This package depends on the following NuGet packages:
- xunit.assert (2.9.2) - Unit testing assertions
- xunit.extensibility.core (2.9.0) - xUnit core functionality
- NSubstitute (5.1.0) - Mocking framework
Requirements
- .NET 8.0 or later
- xUnit testing framework
- NSubstitute mocking framework
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
This project is licensed under the MIT License - see the LICENSE.txt file for details.
Support
For support and questions, please contact the AstreCode development team.
Changelog
See CHANGELOG.md for version history and changes.
AstreCode.Backend.Shared.UnitTest - Version 8.0.0
| 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
- AstreCode.Backend.Shared.Application (>= 9.0.0)
- AstreCode.Backend.Shared.Domain (>= 9.0.0)
- AutoMapper (>= 13.0.1)
- Azure.Storage.Blobs (>= 12.24.0)
- BCrypt.Net-Next (>= 4.0.3)
- File.TypeChecker (>= 4.1.1)
- Hangfire.AspNetCore (>= 1.8.20)
- Hangfire.Core (>= 1.8.20)
- Hangfire.PostgreSql (>= 1.20.12)
- JetBrains.Annotations (>= 2024.2.0)
- Microsoft.AspNetCore.Http (>= 2.2.2)
- Microsoft.AspNetCore.Mvc.Core (>= 2.2.5)
- Microsoft.AspNetCore.StaticFiles (>= 2.2.0)
- Microsoft.AspNetCore.WebUtilities (>= 9.0.8)
- Microsoft.EntityFrameworkCore (>= 9.0.8)
- Microsoft.Extensions.Caching.StackExchangeRedis (>= 9.0.8)
- Microsoft.Extensions.Localization (>= 9.0.8)
- Microsoft.IdentityModel.Tokens (>= 8.0.1)
- NSubstitute (>= 5.1.0)
- RabbitMQ.Client (>= 6.8.1)
- Scrutor (>= 4.2.2)
- StackExchange.Redis (>= 2.8.16)
- System.Linq.Dynamic.Core (>= 1.4.6)
- xunit.assert (>= 2.9.2)
- xunit.extensibility.core (>= 2.9.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.