How it works...

Now that we have created our first test, let's examine the code in detail.

We will first look at the following annotations that have been declared for the BookPubApplicationTests class:

  • @RunWith(SpringRunner.class): This is a standard JUnit annotation that we can configure so as to use the SpringRunner, providing functionality to bootstrap the Spring Boot framework to the standard JUnit tests.
  • @SpringBootTest(webEnvironment=SpringBootTest.WebEnvironment.RANDOM_PORT): This is an annotation that marks the class as a Spring Boot test. It will use the Spring Boot framework to configure the test class instance, provide appropriate configuration, autowiring, and so on. The webEnvironment=SpringBootTest.WebEnvironment.RANDOM_PORT attribute means that the current test is going to use a real, running service instance and will require a complete context initialization and application startup, as if it were the real deal. The RANDOM_PORT value is used to tell Spring Boot to start the Tomcat server on a randomly-chosen HTTP port, which we will later obtain by declaring the @LocalServerPortprivate int port; value field. This ability to select a random HTTP port is very handy when running tests on a Jenkins or any other CI server where, if multiple jobs are running in parallel, you could encounter port collision.

With the class annotations magic dispelled, let's look at the content of the class itself. As this is a Spring Boot test, we can declare any objects that are managed by Spring to be @Autowired during the execution or set to a specific environment value using a @Value annotation. In our test, we autowired the WebApplicationContext and BookRepository objects, as well as an instance of TestRestTemplate, which we will use in the execution of the standard JUnit @Test annotated test cases.

In the first test case, the contextLoads() method, we will just assert that we have the BookRepository connection established and that it contains one book entry.

Our second test will ensure that our web application responds to a RESTful URL for a Book lookup via ISBN - "/books/{isbn}". For this test, we will use the instance of TestRestTemplate and make a RESTful call to the running instance on a randomly-selected port. Spring Boot provides the value of the port field.

In the webappBookIsbnApi test, we are using a full URL with the starting part being "http://localhost:" + port, which is technically not required if TestRestTemplate was autowired and injected by Spring Boot. In this case, it is possible to use a relative URL, looking like Book book = restTemplate.getForObject("/books/978-1-78528-415-1", Book.class);, and TestRestTemplate will automatically determine the port of the running test server instance.

Alternatively, we can execute the same flavor of tests by going through the MockMvc object. This is provided by the Spring Test Framework and allows you to perform MVC testing without actually doing client-side-based testing through RestTemplate, but instead doing it fully on the server side where the controller requests are executed from the same context as the tested application.

In order to use MockMvc, we will use the MockMvcBuilders utility to build an instance using @Autowired WebApplicationContext. We will do this in the setup method so that we don't have to do it in every test explicitly.

It is also possible to get Spring Boot to automatically create an instance of MockMvc, if we annotate our test using WebEnvironment.MOCK instead of RANDOM_PORT. That configuration will only make the test run in the mock context, and no real server will be started. Our example shows how to combine having a real server instance and MockMVC in the same test class.

MockMvc provides us with a very extensive set of capabilities in order to execute assertions on practically all the things that are related to a web request. It is designed to be used in a method-chained fashion, allowing us to link the various tests together and forming a nice, continuous logical chain:

  • perform(get(...)): This method sets up the web request. In our particular case, we perform a GET request but the MockMvcRequestBuilders class provides us with static helper functions for all the common method calls.
  • andExpect(...): This method can be invoked multiple times, where each call represents an evaluation of a condition against the result of the perform(...) call. The argument of this call is any implementation of the ResultMatcher interface along with many stock ones that are provided by the MockMvcResultMatchers static utility class. This really opens up the possibility of having an infinite number of different checks such as verifying the response status, content type, values stored in a session, flash scope, verify redirects, contents of the rendering model or headers, and much more. We will use a third-party json-path add-on library (which is automatically brought as a spring-boot-test dependency) to test the JSON response data in order to ensure that it contains the right elements in the right tree hierarchy. andExpect(jsonPath("$.name").value("Packt")) validates that we have a name element at the root of the JSON document with a value of Packt.
To learn more about the various possibilities that are available in MockMvc, you can refer to https://github.com/spring-projects/spring-mvc-showcase/tree/master/src/test/java/org/springframework/samples/mvc.
..................Content has been hidden....................

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