How to write a unit test for a Spring Boot Controller endpoint
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
For a Spring Boot controller, the fastest useful test is usually a web-slice test rather than a full application boot. The idea is to load the controller, mock the service layer, send an HTTP request through MockMvc, and verify the status code and response body.
Choose the Right Test Scope
A controller test is not the place to prove that JPA, Kafka, or the full application context works. If you want to verify only request mapping, validation, serialization, and HTTP behavior, use @WebMvcTest.
That gives you a focused test:
- controller and MVC infrastructure are loaded
- collaborators such as services are mocked
- tests run much faster than
@SpringBootTest
If you need the whole stack, use integration tests separately. Do not turn every controller test into a full application startup.
Example Controller
Here is a small controller that returns a user by id:
The controller depends only on UserService, which makes it easy to mock.
Write the Test With MockMvc
Now test the endpoint behavior:
This test checks routing, JSON serialization, and status handling without bringing in the full application.
What to Assert
A good controller test normally verifies:
- HTTP status code
- response JSON or body text
- headers when they matter
- input validation behavior
- whether the controller delegates correctly to the service
It usually should not assert internal implementation details that belong to the service or repository layers.
When to Use SpringBootTest Instead
If your endpoint behavior depends on security filters, custom Jackson configuration, real database state, or multiple layers working together, @WebMvcTest may be too narrow. In that case, write an integration test with @SpringBootTest and possibly @AutoConfigureMockMvc.
The important point is separation. Use focused controller tests for controller behavior and a smaller number of slower integration tests for end-to-end wiring.
For endpoints that accept request bodies, add tests for malformed JSON and validation failures as well. A controller is often responsible for returning the correct 400 response when input is syntactically valid HTTP but semantically invalid for the API contract.
Common Pitfalls
A common mistake is mocking too much. If the controller test is full of mocked HTTP details, you are no longer testing the controller; you are testing your own mocks.
Another mistake is using @SpringBootTest for every endpoint test. That slows the suite down and hides the controller's actual responsibility.
A third mistake is forgetting JSON assertions. A 200 OK response alone does not prove that the endpoint returned the correct data shape.
Summary
- Use
@WebMvcTestandMockMvcfor focused Spring Boot controller tests. - Mock the service layer with
@MockBeanso the controller can be tested in isolation. - Assert status codes, JSON content, and validation behavior.
- Reserve
@SpringBootTestfor full-stack integration scenarios. - Keep controller tests narrow so they stay fast and easy to diagnose.

