[Spring Boot] TDD with Spring Boot Starter Security & JWT

Jay Kim
2 min readMay 19, 2021

This article is focused on how to test drive a Spring Boot application using Spring Security. I decided to put this together because there is a lot of Spring involved when using Spring Security and because of that testing can be a little bit difficult and slow.

Full source code can be found here:

Overview

Before test driving, I tried to discover how Spring Security works. There are many ways of creating an authentication system with Spring Security but these are the steps (implementation details) I found to be working for my sample application:

  • Create a domain object or entity that implements UserDetails
  • Create a service that implements UserDetailsService
  • Create a Security Configuration class with @EnableWebSecurity for endpoint access.
  • Provide a JWT token generator when login succeeds
  • Create a filter which gets Authorization header from incoming request and authenticates
  • Apply the filter created above in the Security Configuration

For test driving approach, outside-in (e.g. controller → service → repository) will be used for this problem. Along test driving, some of the implementation details above will be used.

Dependencies

In this example, JUnit5 will be used as main testing library and JJWT will be used for generating and parsing JWT tokens.

Gradle Dependencies

Sign Up

Sign Up Controller Unit Tests

Unit Test for SignupController
Implementation of SignupController

Sign Up Controller Integration Tests

This can be used to drive out some configuration in SecurityConfiguration.

Integration Test to see if /signup is accessible

This will lead to overriding configure(HttpSecurity) method.

Security Configuration

Login

Login Controller Unit Tests

Unit Test for LoginController
Implementation of LoginController

Token Generator Unit Tests

Unit Test for TokenGenerator
Implementation of TokenGenerator

Login Controller Integration Tests

More tests can be added to validate access to different endpoints to existing integration tests inEndpointAccessTests.java.

Integration Test for LoginController

This will lead to implementation changes to allow /login to previous SecurityConfiguration.java.

Security Configuration

Authentication

Filter Unit Tests

Unit Test for Spring Filter
Filter Implementation for setting authentication

User Service Unit Tests

From here it can noticed that UserDetailsService::loadUserByUsername is not yet implemented. So it is possible to test drive from here.

Unit Test for UserDetailsService Implementation
Implementation of UserDetailsService

Integration tests for applying Filter

Lastly, the endpoints that require authentication need to be tested. We already built sign up and login, so we can make use of them to test the access to authenticated endpoints.

Final version of Integration Tests to validate endpoint access

The filter that was implemented above can be added to previousSecurityConfiguration. This will validate and authenticate the Bearer token in the incoming request.

Final version of SecurityConfiguration.java

--

--