Step-by-step instructions
These instructions follow on from what was achieved in the previous lesson.
Add integration test to app subproject
-
in app’s build script, add a new testImplementation dependency on spring-boot-starter-test
testImplementation("org.springframework.boot:spring-boot-starter-test:2.6.4")
-
configure test task to use JUnit 5 (also known as JUnit Jupiter)
testing { suites { named("test", JvmTestSuite::class) { useJUnitJupiter() } } }
-
under src create directories test/java/com/tomgregory/maxirail
-
add a MaxiRailIT.java class
package com.tomgregory.maxirail; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import static org.hamcrest.Matchers.hasSize; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @ExtendWith(SpringExtension.class) @SpringBootTest @AutoConfigureMockMvc public class MaxiRailIT { @Autowired private MockMvc mockMvc; @Test public void getsAllTrainTimes() throws Exception { mockMvc.perform(MockMvcRequestBuilders.get("/") .accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(jsonPath("$", hasSize(4))) .andReturn(); } }
-
run
./gradlew test
and see that the test passes -
view test report in build directory of app subproject
Add unit test to service subproject
-
in service’s build script configure test task to use JUnit 5 (also known as JUnit Jupiter)
testing { suites { named("test", JvmTestSuite::class) { useJUnitJupiter() } } }
-
under src create directories test/java/com/tomgregory/maxirail/service
-
add a TrainTimeServiceTest.java class
package com.tomgregory.maxirail.service; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; public class TrainTimeServiceTest { @Test public void swapsDestinationStationToUppercase() { TrainTimeService trainTimeService = new TrainTimeService(); assertEquals("BRIGHTON", trainTimeService.getTrainTimes().get(0).destinationStation()); assertEquals("BRIGHTON", trainTimeService.getTrainTimes().get(1).destinationStation()); assertEquals("LONDON", trainTimeService.getTrainTimes().get(2).destinationStation()); assertEquals("LONDON", trainTimeService.getTrainTimes().get(3).destinationStation()); } }
-
run the test with
./gradlew test
and see it fail -
make the test pass by updating the destination station names in TrainTimeService.java
package com.tomgregory.maxirail.service; import com.tomgregory.maxirail.model.TrainTime; import org.springframework.stereotype.Service; import java.time.LocalTime; import java.util.Arrays; import java.util.List; @Service public class TrainTimeService { public List<TrainTime> getTrainTimes() { return Arrays.asList( new TrainTime("London", "BRIGHTON", LocalTime.of(9, 30), LocalTime.of(10, 30)), new TrainTime("London", "BRIGHTON", LocalTime.of(15, 0), LocalTime.of(16, 0)), new TrainTime("Brighton", "LONDON", LocalTime.of(11, 0), LocalTime.of(12, 0)), new TrainTime("Brighton", "LONDON", LocalTime.of(16, 30), LocalTime.of(17, 30)) ); } }
-
run the test again with
./gradlew test --console=verbose
. This time it passes. -
note that it also runs tests against the app subproject. You can avoid that by running the test task specifically on the service subproject, using the fully qualified task name.
-
run
./gradlew service:test --console=verbose
Awesome! You now know how and when to execute tasks against specific subprojects.
GitHub repository
The gradle-multi-project-masterclass repository contains the final code solution for lessons 2-5.