Introduction
Testing is a critical part of building reliable microservices. This tutorial walks you through unit, integration, and contract testing strategies using .NET 8.
Prerequisites
- .NET 8 SDK
- Visual Studio 2022 or VS Code
- Docker (optional for external services)
- Basic knowledge of microservice architecture
Setup Test Project
Create a dedicated test project for each service.
dotnet new sln -n MyMicroservice
dotnet new webapi -n OrdersService
dotnet new xunit -n OrdersService.Tests
dotnet sln add OrdersService/OrdersService.csproj
dotnet sln add OrdersService.Tests/OrdersService.Tests.csproj
dotnet add OrdersService.Tests/OrdersService.Tests.csproj reference ../OrdersService/OrdersService.csproj
Unit Testing with xUnit
Focus on business logic isolated from infrastructure.
public class OrderServiceTests
{
[Fact]
public void CreateOrder_ShouldReturnValidOrder()
{
var repo = new Mock();
var service = new OrderService(repo.Object);
var result = service.CreateOrder(new OrderDto { ProductId = 1, Quantity = 2 });
Assert.NotNull(result);
Assert.Equal(2, result.Quantity);
}
}
Integration Testing
Leverage Microsoft.AspNetCore.Mvc.Testing
to host the API in-memory.
public class OrdersApiTests : IClassFixture
{
private readonly HttpClient _client;
public OrdersApiTests(WebApplicationFactory<Program> factory)
{
_client = factory.CreateClient();
}
[Fact]
public async Task GetOrders_ReturnsOk()
{
var response = await _client.GetAsync("/api/orders");
response.EnsureSuccessStatusCode();
var json = await response.Content.ReadAsStringAsync();
Assert.Contains("orders", json);
}
}
Contract Testing
Use Pact to verify provider contracts.
// Provider test (Orders Service)
[Test]
public async Task EnsureProviderMeetsPact()
{
var pactVerifier = new PactVerifier();
await pactVerifier
.ServiceProvider("OrdersService", "http://localhost:5000")
.HonoursPactWith("OrderConsumer")
.PactUri("pacts/orderconsumer-ordersservice.json")
.VerifyAsync();
}
CI/CD Integration
Example GitHub Actions workflow snippet:
name: Build and Test
on:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: '8.0.x'
- name: Restore
run: dotnet restore
- name: Build
run: dotnet build --no-restore
- name: Test
run: dotnet test --no-build --verbosity normal
Summary
By combining unit, integration, and contract tests, you can achieve high confidence in your microservices. Integrate these tests into your CI pipeline to catch regressions early.