Introduction
Integration tests hit ShopNest API through WebApplicationFactory — real HTTP pipeline, real middleware, test database — catching wiring bugs unit tests miss.
After this article you will
- Use WebApplicationFactory for in-memory test server
- Call endpoints with HttpClient and assert responses
- Configure SQLite or test SQL Server database
- Authenticate test requests with JWT or test auth handler
- Reset database state between tests with fixtures
Prerequisites
- Article 54 — Unit Testing with xUnit and Moq
- ShopNest Order Service / API from prior modules
Concept deep-dive
public class ShopNestApiFactory : WebApplicationFactory<Program>
{
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.ConfigureServices(services =>
{
var descriptor = services.SingleOrDefault(
d => d.ServiceType == typeof(DbContextOptions<ShopNestDbContext>));
if (descriptor != null) services.Remove(descriptor);
services.AddDbContext<ShopNestDbContext>(options =>
options.UseSqlite("DataSource=file:shopnest-test.db?mode=memory&cache=shared"));
});
builder.UseEnvironment("Testing");
}
}
[Fact]
public async Task PostOrder_Returns201()
{
var client = _factory.CreateClient();
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", _factory.GetTestJwt());
var response = await client.PostAsJsonAsync("/api/v1/orders", validOrder);
response.StatusCode.Should().Be(HttpStatusCode.Created);
}
Unit vs integration: Unit = fast, isolated logic. Integration = slower, tests HTTP + DI + DB together.
Hands-on — ShopNest REST API End-to-End Testing
- ShopNest.Api.IntegrationTests project.
- WebApplicationFactory + SQLite in-memory shared connection.
- Seed products; POST order; GET order by id — full flow.
- IClassFixture<ShopNestApiFactory> for shared factory.
- Respawn or recreate DB per test class.
Common errors & best practices
- Sharing mutable DB without reset — test order dependency failures.
- Testing against production connection string — never.
- Not replacing external APIs — use TestServer handler or WireMock.
Interview questions
Q: WebApplicationFactory?
A: Boots full app in memory for HttpClient tests without Kestrel network.
Q: When integration vs unit?
A: Unit for logic; integration for routes, auth, serialization, EF queries together.
Q: Test auth?
A: Test auth handler, pre-generated JWT, or WebApplicationFactory custom claims.
Summary
- WebApplicationFactory enables realistic API tests
- SQLite in-memory fast for CI pipelines
- Integration suite catches DI and middleware bugs
- Fixtures share expensive startup once per class
Previous: Unit Testing with xUnit and Moq
Next: Testing EF Core
FAQ
FluentAssertions?
Popular readable asserts — response.Should().BeSuccessful().
Testcontainers?
Spin real SQL Server in Docker for closer production parity.