Integration test

Integration tests are very similar to unit tests, and many times, novice programmers claim they do unit testing when they actually do integration testing.

Integration tests drive the code but do not test the individual classes (units) in isolation, mocking everything that the class may use. Rather, they test the functionality of most of the classes that are needed to perform a test. This way, the integration test does test that the classes are able to work together and not only satisfy their own specifications but also ensure that these specifications work together.

In integration test, the external world (like external services) and access to database are mocked only. That is because the integration tests are supposed to run on integration servers, in the same environment where the unit tests are executed, and there these external interfaces may not be available. Many times, databases are mocked using in-memory SQL, and external services are mocked using some mock classes.

Spring provides a nice environment to execute such integration tests. In our project, we have a sample integration test:

package packt.java9.by.example.mybusiness.productinformation; 
import ...
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
@AutoConfigureMockMvc
@ActiveProfiles("local")
public class ProductInformationControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
public void noParamGreetingShouldReturnDefaultMessage()
throws Exception {
this.mockMvc.perform(get("/pi")).andDo(print())
.andExpect(status().isNotFound());
}
@Test
public void paramGreetingShouldReturnTailoredMessage()
throws Exception {

this.mockMvc.perform(get("/pi/123"))
.andDo(print()).andExpect(status().isOk())
.andExpect(jsonPath("$.title")
.value("Book Java 9 by Example"));
}

}

This is far from being a complete and full-fledged integration test. There are many situations that are not tested, but here it is good as an example. To have all the support for the Spring environment, we have to use the SpringRunner class. The @RunWith annotation is handled by the JUnit framework, all other annotations are for Spring. When the JUnit framework sees that there is a @RunWith annotation and a runner class specified, it starts that class instead of the standard runner. SpringRunner sets up a Spring context for the test and handles the annotations.

@SpringBootTest specifies the applications that we need to test. This helps Spring to read that class and the annotation on that class, identifying the packages to be scanned.

@AutoConfigureMockMvc tells Spring to configure a mock version of the Model View Controller framework, which can be executed without a servlet container and web protocol. Using that, we can test our REST services without really going to the network.

@ActiveProfiles tells Spring that the active profile is local and that Spring has to use the configuration that is denoted by the annotation, @Profile("local"). This is a version that uses the .properties files instead of external HTTP services; thus, this is appropriate for integration testing.

The test performs GET requests inside the mocking framework, executes the code in the controller, and tests the returned value using the mocking framework and fluent API in a very readable way.

Note that using the properties files and having the service implementation based on properties file is a bit of an overkill. I created this so that it is possible to start up the application interactively without any real backing service. Consider the following command: gradle -Dspring.profiles.active=local bootRun .
If we issue the preceding command, then the server starts up using this local implementation. If we only aim for integration testing, then the local implementation of the service classes should be under the test directory and should be much simpler, mainly only returning constant responses for any expected request and throwing errors if any non-expected request comes.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.206.25