Skip to main content

Backend Testing

Functionality required by the "Pflichtenheft" must be tested.

Spring Boot Controller Testing

Scope

We only test at the controller layer, verifying the correct HTTP behavior, request/response mapping, validation, and controller-service interaction. (→ Blackbox-Testing)
No mocking of the controller, but mocking/stubbing of lower layers (e.g., services or repositories) is allowed when needed.

Default Tools

  1. Spring Boot Test ( @SpringBootTest) – for full application context tests (optional, slower).
  2. @WebMvcTest – for isolated controller tests (recommended for speed and focus).
  3. MockMvc – to simulate HTTP requests to the controller.
  4. Mockito – for mocking services under the controller.
  5. AssertJ / Hamcrest – for fluent assertions.
  6. JUnit 5 – as default test engine.

Testing Approach

  • Use @WebMvcTest(YourController.class) to load only the web layer.
  • Inject MockMvc to perform requests.
  • Mock external services (e.g., service layer beans) with @MockBean.
  • Cover at least:
    • Request mapping
    • Validation rules
    • Expected response codes and JSON bodies

Example Controller Test

Let's say we have this simple controller:

@RestController
@RequestMapping("/api/users")
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}

@GetMapping("/{id}")
public ResponseEntity<UserDto> getUser(@PathVariable Long id) {
return ResponseEntity.ok(userService.getUserById(id));
}
}

Here’s a corresponding controller test: (this file should lay inside src/test/java/com/agilesoftwareengineering/[your-application]/UserControllerTest.class)

@WebMvcTest(UserController.class)
class UserControllerTest {

@Autowired
private MockMvc mockMvc;

@MockBean
private UserService userService;

@Test
void shouldReturnUserById() throws Exception {
UserDto user = new UserDto(1L, "Alice");
Mockito.when(userService.getUserById(1L)).thenReturn(user);

mockMvc.perform(get("/api/users/1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.id").value(1))
.andExpect(jsonPath("$.name").value("Alice"));
}
}

Notes

  • Stick to controller-only logic (i.e., no testing service/repo logic here).
  • Run these tests on every merge or pull request.
  • Consider using Testcontainers if you eventually expand to integration testing (e.g., testing DB + controller together).