How do you make a Web API testable?

Web API & REST ASP.NET Core APIs Intermediate 2–3 Yrs3–5 Yrs Architecture 1 min read

Quick Answer

Keep controllers/endpoints thin — bind, delegate to a service or handler, map the result to a status code. The logic lives in injectable services you unit-test in isolation. Test the HTTP layer (routing, filters, serialization, auth) with an integration test via WebApplicationFactory.

The main thing is keeping the controller thin — it binds the request, calls a service or a handler, and turns the result into a status code. All the actual logic is in injectable services, and those I unit-test on their own with the dependencies mocked, which is fast and lets me cover lots of edge cases. Then I write a handful of integration tests through WebApplicationFactory to prove the HTTP plumbing works — routing, filters, serialization, auth. If the controller has a DbContext and business rules in it, it's hard to test and that's the smell.

  • A controller action should be a few lines: var result = await _service.DoAsync(dto); return result.IsSuccess ? Ok(result.Value) : NotFound();.
  • No DbContext, no business rules, no new-ing dependencies in the controller.
  • Unit-test the service with mocked dependencies (fast, many cases); integration-test a few end-to-end happy/sad paths.
  • MediatR makes this natural — the controller sends a request, the handler is the unit under test.