Level 7 - Milestone 13
Milestone 13 - Integration Testing the Home Controller
In this section we will add an integration test for our HomeController method.
Before completion of this milestone, students will:
- Learn how to write a basic integration test.
Creating a Class for the Integration Test
Add a HomeControllerIntTest class inside the appropriate folder within the IntTest source set, keep in mind that the structure reflects the structure of our main and test source sets.
Using @WebMvcTest
With our integration tests, we will issue a "fake" request to our application, and check to see
that
Spring invokes the correct method when a request is made to a certain endpoint. Notice how this
differs from our unit tests: in our unit tests we used an instance of an object to invoke a
method
directly, and check that it returned the expected result. Here, we are taking a step back and
checking that when a request is issued to a certain URL, that Spring and the code that we wrote
end up doing the correct thing.
Because we are testing that the application responds correctly to a request, rather than a
single
method in isolation, we need to bring up the Spring part of the application to conduct these
tests.
It is because we need to run the application as a whole for our integration tests, that
integrations test take much long to run that unit tests.
In order to launch Spring for our integration test, we need another annotation: @WebMcvTest.
This
will be added right about the class definition for our HomeControllerIntTest. This annotation
auto-configures the Spring MVC infrastructure and the MockMVC (that will discuss shortly) for
use with our tests.
In our integration tests, we aren't going to mention any classes specifically, as we rely on
Spring
to test the mapping between a given URL and the method that is called, but we can improve our
@WebMvcTest annotation
to make our tests a little more efficient. Instead of having our integration test bring up the
entire
Spring context for our application, we can give it a "hint" as to which slice of the application
is needed
for this tests. This will allow us to only start up the slice of the application that is under
tests here,
making it run much more quickly. We can update the class annotation to
"@WebMvcTest(HomeController.class)"
to accomplish this.
Adding MockMvc Dependency to the Class
In preparation for the next step, add a "private MockMvc mockMvc" field to the class, with an @Autowired annotation above it so that it is automatically instantiated.
Adding the Integration Test Method
The basis of the test method will look just as it does in the unit tests. In this case, something like the following would be appropriate:
@Test public void whenHome_ThenReturnMovedPermanentlyAndRedirect() { }
Completing the Test Method
We will use the MockMvc we created previously to execute the integration test. In general, the structure of the test will be somewhat similar to our unit tests: we will execute something, and then tests that the result is what we expected. For our integration tests, however, the syntax for will be considerable different since we are using this MockMvc to issue a request instead of calling a method directly. In the case of our HomeController method, we want to test that when a request is sent to the root URL, "/", that two things occur. First, that an "Move Permanently" status code is returned, and second that the String that redirects our use to our swagger page is sent. We will also print our some additional things. This makes it easy to see what went wrong in the even that our test fails. The code that executes this is pretty readable, and reproduced here:
@Test public void givenController_WhenHome_ThenReturnMovedPermanentlyAndRedirect() throws Exception { mockMvc.perform(get("/")) .andDo(print()) .andExpect(status().isMovedPermanently()) .andExpect(redirectedUrl("swagger-ui.html")); }
Run the Test
At this point our test is complete. You should be able to run it and see that it passes. Remember that at this point there are multiple ways for you to run your tests. You can run it using one of the play buttons in the IDE gutter, or use the the Gradle "intTest" or "check" tasks.
Summary of Code Changes for this Milestone
-
Cheetah-Search
- src
- intTest
- java
- org.jointheleague.level7.cheetah
- presentation
- main
- java
- org.jointheleague.level7.cheetah
- config
- ApiDocConfig.java
- presentation
- HomeController.java
- LocController.java
- service
- LocService.java
- repository
- dto
- Result.java
- LocResponse.java
- LocRepository.java
- resources
- application.yml
- test
- java
- org.jointheleague.level7.cheetah
- presentation
- HomeControllerTest.java
- LocControllerTest.java
- service
- LocServiceTest.java
- repository
- LocRepositoryTest.java
- build.gradle