JavaBeat

  • Home
  • Java
    • Java 7
    • Java 8
    • Java EE
    • Servlets
  • Spring Framework
    • Spring Tutorials
    • Spring 4 Tutorials
    • Spring Boot
  • JSF Tutorials
  • Most Popular
    • Binary Search Tree Traversal
    • Spring Batch Tutorial
    • AngularJS + Spring MVC
    • Spring Data JPA Tutorial
    • Packaging and Deploying Node.js
  • About Us
    • Join Us (JBC)
  • Privacy

Spring Boot : Integration Testing REST API in Spring Boot

June 27, 2015 by Mohamed Sanaulla Leave a Comment

This tutorial explains how to write the integration testing REST API in Spring Boot. This tutorial uses the examples written in the previous tutorial. This tutorial intends to create the automated testing using JUnit and runs with Spring Boot application.

This tutorial assumes the reader has enough already knowledge on the Spring REST web services. If you want to learn basic details of Spring We Services, please read our Introduction to Spring Web Services.

Integration Testing REST API in Spring Boot

Automation testing is the most efficient way of doing the testing and save the cost for company by reducing the man power. This tutorial on how to write the integration testing REST API in Spring Boot application, would definitely help you to convert your existing REST projects into fully integrated testing environment.

Are you looking for more tutorials on Spring Framework :: Visit our Best Spring Tutorials 

I wrote about building RESTful applications and also tested the same using Postman RESTful Client. But in an ideal scenario I would have to automate the testing of these RESTful APIs. In this post I am going to show you how exactly to do the integration testing for REST API using Spring Boot. I have written the complete code in my Github, you can access it for more details about the implementation.

Integration Testing REST API in Spring Boot

Firstly we need to add appropriate dependencies in the pom.xml for testing which is given below:

[code language=”xml”]
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
[/code]

JUnit Integration Testing Class for REST API

We are going to write the test classes using the JUnit library. Once we have completed the test class, we have to run this class from our environment. It can be done easily from the IDEs like Eclipse which supports JUnit execution as built-in functionality. Lets annotate the Controller test class as shown below:

[code language=”java”]
package app.controller;

import org.junit.runner.RunWith;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.WebIntegrationTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import app.Application;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebIntegrationTest
public class BookControllerTest {

//Required to Generate JSON content from Java objects
public static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

//Required to delete the data added for tests.
//Directly invoke the APIs interacting with the DB
@Autowired
private BookRepository bookRepository;

//Test RestTemplate to invoke the APIs.
private RestTemplate restTemplate = new TestRestTemplate();

}
[/code]

In the above code:

  • SpringJUnit4ClassRunner is a custom extension of JUnit’s BlockJUnit4ClassRunner which provides functionality of the Spring TestContext Framework.
  • @SpringApplicationConfiguration is a Class-level annotation that is used to determine how to load and configure an ApplicationContext for integration tests. We provide it with the configuration class which in this case is Application class.
  • @WebIntegrationTest Test class annotation signifying that the tests are “web integration tests” and therefore require full startup in the same way as a production application.

Also we need to specify the port at which the test server would run, among other approaches I prefer to create a application.properties file in the src/test/resources directory. The contents of that file is given below:

[code]
server.port = 8888
[/code]

With the above setup lets now individually test the APIs.

Testing the Create Book API

As given in the API design for Creating Book here, we need to pass the JSON of following format in Request body:

[code language=”javascript”]
{
"name" : "Book 3",
"isbn": "45567",
"author" : "Author 3",
"pages" : 200
}
[/code]

Below is the code for testing the Create API:

[code language=”java”]
@Test
public void testCreateBookApi() throws JsonProcessingException{

//Building the Request body data
Map<String, Object> requestBody = new HashMap<String, Object>();
requestBody.put("name", "Book 1");
requestBody.put("isbn", "QWER1234");
requestBody.put("author", "Author 1");
requestBody.put("pages", 200);
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setContentType(MediaType.APPLICATION_JSON);

//Creating http entity object with request body and headers
HttpEntity<String> httpEntity =
new HttpEntity<String>(OBJECT_MAPPER.writeValueAsString(requestBody), requestHeaders);

//Invoking the API
Map<String, Object> apiResponse =
restTemplate.postForObject("http://localhost:8888/book", httpEntity, Map.class, Collections.EMPTY_MAP);

assertNotNull(apiResponse);

//Asserting the response of the API.
String message = apiResponse.get("message").toString();
assertEquals("Book created successfully", message);
String bookId = ((Map<String, Object>)apiResponse.get("book")).get("id").toString();

assertNotNull(bookId);

//Fetching the Book details directly from the DB to verify the API succeeded
Book bookFromDb = bookRepository.findOne(bookId);
assertEquals("Book 1", bookFromDb.getName());
assertEquals("QWER1234", bookFromDb.getIsbn());
assertEquals("Author 1", bookFromDb.getAuthor());
assertTrue(200 == bookFromDb.getPages());

//Delete the data added for testing
bookRepository.delete(bookId);

}
[/code]

Testing the Get Book Details API

Now lets test the API that is used to fetch the details of the Book.

[code language=”java”]
@Test
public void testGetBookDetailsApi(){
//Create a new book using the BookRepository API
Book book = new Book("Book1", "ÏSBN1", "Author1", 200);
bookRepository.save(book);

String bookId = book.getId();

//Now make a call to the API to get details of the book
Book apiResponse = restTemplate.getForObject("http://localhost:8888/book/"+ bookId, Book.class);

//Verify that the data from the API and data saved in the DB are same
assertNotNull(apiResponse);
assertEquals(book.getName(), apiResponse.getName());
assertEquals(book.getId(), apiResponse.getId());
assertEquals(book.getIsbn(), apiResponse.getIsbn());
assertEquals(book.getAuthor(), apiResponse.getAuthor());
assertTrue(book.getPages() == apiResponse.getPages());

//Delete the Test data created
bookRepository.delete(bookId);
}
[/code]

Testing the Update Book API

[code language=”java”]
@Test
public void testUpdateBookDetails() throws JsonProcessingException{
//Create a new book using the BookRepository API
Book book = new Book("Book1", "ISBN1", "Author1", 200);
bookRepository.save(book);

String bookId = book.getId();

//Now create Request body with the updated Book Data.
Map<String, Object> requestBody = new HashMap<String, Object>();
requestBody.put("name", "Book2");
requestBody.put("isbn", "ISBN2");
requestBody.put("author", "Author2");
requestBody.put("pages", 200);
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setContentType(MediaType.APPLICATION_JSON);

//Creating http entity object with request body and headers
HttpEntity<String> httpEntity =
new HttpEntity<String>(OBJECT_MAPPER.writeValueAsString(requestBody), requestHeaders);

//Invoking the API
Map<String, Object> apiResponse = (Map)restTemplate.exchange("http://localhost:8888/book/" + bookId,
HttpMethod.PUT, httpEntity, Map.class, Collections.EMPTY_MAP).getBody();

assertNotNull(apiResponse);
assertTrue(!apiResponse.isEmpty());

//Asserting the response of the API.
String message = apiResponse.get("message").toString();
assertEquals("Book Updated successfully", message);

//Fetching the Book details directly from the DB to verify the API succeeded in updating the book details
Book bookFromDb = bookRepository.findOne(bookId);
assertEquals(requestBody.get("name"), bookFromDb.getName());
assertEquals(requestBody.get("isbn"), bookFromDb.getIsbn());
assertEquals(requestBody.get("author"), bookFromDb.getAuthor());
assertTrue(Integer.parseInt(requestBody.get("pages").toString()) == bookFromDb.getPages());

//Delete the data added for testing
bookRepository.delete(bookId);

}
[/code]

Testing the Delete Book API

[code language=”java”]
@Test
public void testDeleteBookApi(){
//Create a new book using the BookRepository API
Book book = new Book("Book1", "ISBN1", "Author1", 200);
bookRepository.save(book);

String bookId = book.getId();

//Now Invoke the API to delete the book
restTemplate.delete("http://localhost:8888/book/"+ bookId, Collections.EMPTY_MAP);

//Try to fetch from the DB directly
Book bookFromDb = bookRepository.findOne(bookId);
//and assert that there is no data found
assertNull(bookFromDb);
}
[/code]

Testing the Get All Books API

[code language=”java”]
@Test
public void testGetAllBooksApi(){
//Add some test data for the API
Book book1 = new Book("Book1", "ISBN1", "Author1", 200);
bookRepository.save(book1);

Book book2 = new Book("Book2", "ISBN2", "Author2", 200);
bookRepository.save(book2);

//Invoke the API
Map<String, Object> apiResponse = restTemplate.getForObject("http://localhost:8888/book", Map.class);

//Assert the response from the API
int totalBooks = Integer.parseInt(apiResponse.get("totalBooks").toString());
assertTrue(totalBooks == 2);

List<Map<String, Object>> booksList = (List<Map<String, Object>>)apiResponse.get("books");
assertTrue(booksList.size() == 2);

//Delete the test data created
bookRepository.delete(book1.getId());
bookRepository.delete(book2.getId());
}
[/code]

The above code examples are just a part of the whole examples. You can refer my Github page to use the whole sample application on REST integration testing with Spring Book. If you have any questions, please write it in the comments section.

Hope this post gives some clarity on how to write the integration testing REST API in Spring Boot application. This code base along with its relevant REST API code can be found on GitHub here.

Filed Under: Spring Framework Tagged With: Spring Boot Tutorials

About Mohamed Sanaulla

In his day job he works on developing enterprise applications using ADF. He is also the moderator of JavaRanch forums and an avid blogger.

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Follow Us

  • Facebook
  • Pinterest

As a participant in the Amazon Services LLC Associates Program, this site may earn from qualifying purchases. We may also earn commissions on purchases from other retail websites.

JavaBeat

FEATURED TUTORIALS

Answered: Using Java to Convert Int to String

What is new in Java 6.0 Collections API?

The Java 6.0 Compiler API

Copyright © by JavaBeat · All rights reserved