To learn about Spring MVC, I’ve created a personal project that represents a very basic forum application. So far, it’s been going really well, but I’ve hit a snag in trying to get the logout method covered in my JaCoCo report.
Here’s what the logout method looks like in my IndexController:
@RestController
@CrossOrigin(origins = "http://localhost:3000")
public class IndexController {
private final AuthService authService;
private final UserService userService;
@Autowired
public IndexController(@NonNull AuthService authService, @NonNull UserService userService) {
this.authService = authService;
this.userService = userService;
}
// login and signup methods
@PostMapping("/logout")
public ResponseEntity<Void> logout(UUID token) {
authService.logout(token);
return ResponseEntity.ok().build();
}
}
Here’s the authentication service class that handles login/logout requests:
@Service
public class AuthService {
private final UserAccountRepo repo;
private final HashMap<UUID, UUID> tokenMap;
@Autowired
public AuthService(@NonNull UserAccountRepo repo) {
this.repo = repo;
this.tokenMap = new HashMap<>();
}
public LoginResponse login(String username, String password) {
Optional<UserAccount> maybeUser = this.repo.findByUsernameAndPassword(username, password);
if (maybeUser.isEmpty()) {
throw new InvalidCredentialsException("Invalid username or password.");
}
UserAccount user = maybeUser.get();
UUID token = UUID.randomUUID();
this.tokenMap.put(token, user.getId());
String firstName = user.getUserProfile().getFirstName();
return new LoginResponse(token, firstName, username);
}
public void logout(UUID token) {
tokenMap.remove(token);
}
}
The unit test that I wrote to cover the two lines of logic in the logout method of the IndexController goes like this:
@WebMvcTest(IndexController.class)
@ContextConfiguration(classes = {WebSecurityConfig.class,
IndexController.class,
GlobalExceptionHandler.class})
public class IndexControllerUnitTests {
@Autowired
private MockMvc mockMvc;
@MockBean
private AuthService authService;
UUID token = UUID.randomUUID();
@Test
public void testLogout() throws Exception {
// Mock the logout method of authService
Mockito.doNothing().when(authService).logout(token);
// Perform the POST request to the /logout endpoint
mockMvc
.perform(MockMvcRequestBuilders.post("/logout"))
.andExpect(status().isOk());
}
}
The test passes just fine, but JaCoCo says nothing happened:
I’m a little stuck as to how to make this work.
I used a similar approach for all my login tests and it passed successfully and tracked the coverage just fine. Am I dumb?