Testing¶
Overview¶
This section covers testing techniques and best practices for working with the TinyResult library.
Test Strategies¶
Success Result Test¶
[Fact]
public void GetUser_WhenUserExists_ReturnsSuccess()
{
// Arrange
var user = new User { Id = 1, Name = "Test" };
_repository.Setup(r => r.GetUser(1)).Returns(user);
// Act
var result = _service.GetUser(1);
// Assert
result.IsSuccess.Should().BeTrue();
result.Value.Should().BeEquivalentTo(user);
}
Failure Result Test¶
[Fact]
public void GetUser_WhenUserNotFound_ReturnsFailure()
{
// Arrange
_repository.Setup(r => r.GetUser(1)).Returns((User)null);
// Act
var result = _service.GetUser(1);
// Assert
result.IsFailure.Should().BeTrue();
result.Error.Message.Should().Be("User not found");
}
Test Helpers¶
Result Assertions¶
public static class ResultAssertions
{
public static void ShouldBeSuccess<T>(this Result<T> result, T expectedValue)
{
result.IsSuccess.Should().BeTrue();
result.Value.Should().BeEquivalentTo(expectedValue);
}
public static void ShouldBeFailure<T>(this Result<T> result, string expectedMessage)
{
result.IsFailure.Should().BeTrue();
result.Error.Message.Should().Be(expectedMessage);
}
}
Test Data Creation¶
public static class ResultTestData
{
public static Result<User> CreateSuccessResult()
{
return Result<User>.Success(new User { Id = 1, Name = "Test" });
}
public static Result<User> CreateFailureResult()
{
return Result<User>.Failure("Test error");
}
}
Async Tests¶
Async Success Test¶
[Fact]
public async Task GetUserAsync_WhenUserExists_ReturnsSuccess()
{
// Arrange
var user = new User { Id = 1, Name = "Test" };
_repository.Setup(r => r.GetUserAsync(1)).ReturnsAsync(user);
// Act
var result = await _service.GetUserAsync(1);
// Assert
result.IsSuccess.Should().BeTrue();
result.Value.Should().BeEquivalentTo(user);
}
Async Failure Test¶
[Fact]
public async Task GetUserAsync_WhenRepositoryThrows_ReturnsFailure()
{
// Arrange
_repository.Setup(r => r.GetUserAsync(1))
.ThrowsAsync(new Exception("Database error"));
// Act
var result = await _service.GetUserAsync(1);
// Assert
result.IsFailure.Should().BeTrue();
result.Error.Message.Should().Be("Database error");
}
Validation Tests¶
Validation Success Test¶
[Fact]
public void ValidateUser_WhenValid_ReturnsSuccess()
{
// Arrange
var user = new User { Name = "Test", Email = "test@example.com" };
// Act
var result = _validator.Validate(user);
// Assert
result.IsValid.Should().BeTrue();
result.Errors.Should().BeEmpty();
}
Validation Failure Test¶
[Fact]
public void ValidateUser_WhenInvalid_ReturnsErrors()
{
// Arrange
var user = new User { Name = "", Email = "invalid" };
// Act
var result = _validator.Validate(user);
// Assert
result.IsValid.Should().BeFalse();
result.Errors.Should().ContainKey("Name")
.WhoseValue.Should().Be("Name is required");
result.Errors.Should().ContainKey("Email")
.WhoseValue.Should().Be("Email is invalid");
}
Mock and Stub Usage¶
Repository Mock¶
public class UserServiceTests
{
private readonly Mock<IUserRepository> _repository;
private readonly UserService _service;
public UserServiceTests()
{
_repository = new Mock<IUserRepository>();
_service = new UserService(_repository.Object);
}
[Fact]
public void GetUser_WhenUserExists_ReturnsSuccess()
{
// Arrange
var user = new User { Id = 1, Name = "Test" };
_repository.Setup(r => r.GetUser(1)).Returns(user);
// Act
var result = _service.GetUser(1);
// Assert
result.ShouldBeSuccess(user);
_repository.Verify(r => r.GetUser(1), Times.Once);
}
}
Validator Stub¶
public class UserRegistrationServiceTests
{
private readonly Mock<IUserValidator> _validator;
private readonly UserRegistrationService _service;
public UserRegistrationServiceTests()
{
_validator = new Mock<IUserValidator>();
_service = new UserRegistrationService(_validator.Object);
}
[Fact]
public void RegisterUser_WhenValid_ReturnsSuccess()
{
// Arrange
var user = new User { Name = "Test" };
_validator.Setup(v => v.Validate(user))
.Returns(ValidationResult.Create());
// Act
var result = _service.RegisterUser(user);
// Assert
result.ShouldBeSuccess();
}
}
Test Coverage¶
Unit Test Coverage¶
- Result creation
- Result transformation
- Error handling
- Validation
- Async operations
Integration Test Coverage¶
- Repository integration
- Service integration
- API integration
- Database integration