All posts

Testing Error Scenarios in .NET Applications

Learn how to write robust .NET tests for error scenarios including exception handling, fault injection, and edge case validation with xUnit.

Testing Error Scenarios in .NET Applications

Testing the happy path is easy. Testing how your .NET application fails is where real reliability comes from.

Assert Exceptions with xUnit

xUnit provides clean exception assertion patterns:

[Fact]
public async Task GetUser_WithInvalidId_ThrowsNotFoundException()
{
    var service = new UserService(_mockRepo.Object);

    var exception = await Assert.ThrowsAsync<NotFoundException>(
        () => service.GetUserAsync(Guid.Empty)
    );

    Assert.Equal("User not found", exception.Message);
}

Test HTTP Error Responses

Use WebApplicationFactory to test error handling in your API controllers:

[Fact]
public async Task GetOrder_NotFound_Returns404()
{
    var client = _factory.CreateClient();

    var response = await client.GetAsync("/api/orders/nonexistent");

    Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
    var body = await response.Content.ReadFromJsonAsync<ProblemDetails>();
    Assert.Equal("Order not found", body.Detail);
}

Simulate Infrastructure Failures

Use Moq to simulate database and service failures:

[Fact]
public async Task CreateOrder_DatabaseTimeout_ReturnsServiceUnavailable()
{
    _mockRepo.Setup(r => r.SaveAsync(It.IsAny<Order>()))
        .ThrowsAsync(new TimeoutException("Connection timeout"));

    var result = await _controller.CreateOrder(new OrderRequest());

    var statusResult = Assert.IsType<ObjectResult>(result);
    Assert.Equal(503, statusResult.StatusCode);
}

Key Error Scenarios to Cover

  • Validation errors — invalid input returns 400 with details
  • Authentication failures — expired tokens, missing credentials
  • Concurrency conflicts — optimistic concurrency exceptions
  • Timeout handling — external service timeouts degrade gracefully
  • Rate limiting — 429 responses with retry-after headers

Monitor Test Gaps in Production

Even thorough testing misses edge cases. Use Bugsly to track unhandled exceptions in production and convert them into test cases. Each production error should become a regression test, closing the loop between monitoring and testing.

By systematically testing error paths, you build .NET applications that fail gracefully instead of crashing unexpectedly.

Try Bugsly Free

AI-powered error tracking that explains your bugs. Set up in 2 minutes, free forever for small projects.

Get Started Free