- Invade the Code 👽
- Posts
- 🌟 Day 15 of #100DaysOfCode: SpringBoot Testing All Layers 🌟
🌟 Day 15 of #100DaysOfCode: SpringBoot Testing All Layers 🌟
Hey Invaders! 👽
#100DaysOfCode day 15: I started section 11: SpringBoot (Part 2) and learned about writing test methods that engage all three layers of our application. I used the @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
annotation to set up a random port for testing. Additionally, I used @LocalServerPort
to inject the port number and @Autowired
to inject TestRestTemplate
for making HTTP requests during the tests.
Here's a snippet of what I worked on today:
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class UsersControllerIntegrationTest {
@Value("${server.port}")
private int serverPort;
@LocalServerPort
private int localServerPort;
@Autowired
private TestRestTemplate testRestTemplate;
@Test
@DisplayName("user can be created")
void testCreateUser_whenValidDetailsProvided_returnUserDetails() throws JSONException {
//arrange
JSONObject userDetailsRequestJson= new JSONObject();
userDetailsRequestJson.put("firstName", "ari");
userDetailsRequestJson.put("lastName", "vanegas");
userDetailsRequestJson.put("email", "[email protected]");
userDetailsRequestJson.put( "password", "12345678");
userDetailsRequestJson.put( "repeatPassword", "12345678");
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
HttpEntity<String> request = new HttpEntity<>(userDetailsRequestJson.toString(), headers);
//act
ResponseEntity<UserRest> createdUserDetailsEntity = testRestTemplate.postForEntity("/users",
request, UserRest.class);
UserRest createdUserDetails = createdUserDetailsEntity.getBody();
//assert
assertEquals(HttpStatus.OK, createdUserDetailsEntity.getStatusCode());
assertEquals(userDetailsRequestJson.getString("firstName"), createdUserDetails.getFirstName(), "Returned users first name seems to incorrect");
assertEquals(userDetailsRequestJson.getString("lastName"),
createdUserDetails.getLastName(),
"Returned user's last name seems to be incorrect");
assertEquals(userDetailsRequestJson.getString("email"),createdUserDetails.getEmail(), "Returned users email seems to be incorrect" );
assertFalse(createdUserDetails.getUserId().trim().isEmpty(), "user id should not be empty");
}
}
This setup helps ensure that the integration tests cover all layers of the application, providing a more comprehensive validation of functionality. By using @SpringBootTest
, we can create an application context that includes all beans and configurations, allowing for true end-to-end testing.
Key Points Learned:
@SpringBootTest: This annotation is used for integration tests that require the full Spring context. It can be configured with different web environments.
@LocalServerPort: This annotation is used to inject the port number that the application is running on during the test. It is particularly useful when the port is randomly assigned.
TestRestTemplate: This is a convenient alternative to the standard
RestTemplate
that is configured for integration testing. It allows for easy sending of HTTP requests and handling of responses.Full Layer Testing: By using these annotations and setups, we can write tests that cover the controller, service, and repository layers, ensuring that the application behaves as expected from end to end.
This approach to testing is crucial for Spring Boot applications as it provides a high level of confidence in the application's behavior in a production-like environment.
You can check out the rest of my code on github!
Reply