Introduction
In this tutorial we will see how to write Junit test cases on Spring REST services. Before continue to reading this tutorial please read first Spring RESTful Webservice CRUD Example
We have total four operations on this REST example. If you want you may add more operation such as find all products and apply Junit on it.
Prerequisites
Knowledge of Java, Junit, Spring
Spring RESTful Webservice CRUD Example
Example with Source Code
Here we will create the Junit test cases for Spring REST services.
Adding Dependencies
We need to add the required dependencies in order to write Junit test cases for Spring REST services.
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<!-- <scope>test</scope> -->
<exclusions>
<exclusion>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.3.8.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.7.19</version>
<exclusions>
<exclusion>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
</exclusion>
</exclusions>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<version>2.2.0</version>
<scope>test</scope>
</dependency>
</dependencies>
Creating Junit Class
The complete Junit class is given below
package roytuts.rest;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import com.fasterxml.jackson.databind.ObjectMapper;
import roytuts.model.Product;
import roytuts.sevice.ProductService;
@RunWith(MockitoJUnitRunner.class)
public class SpringRestControllerTest {
@Mock
private ProductService service;
private MockMvc mockMvc;
@Spy
@InjectMocks
private SpringRestController controller = new SpringRestController();
@Before
public void init() {
mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
}
@Test
public void testGetProductById() throws Exception {
Product product = new Product();
product.setId(1);
product.setName("Product name");
product.setPrice(21540.00);
Mockito.when(service.findProductById(Mockito.anyInt())).thenReturn(product);
mockMvc.perform(MockMvcRequestBuilders.get("/product/1")).andExpect(MockMvcResultMatchers.status().is(200))
.andExpect(MockMvcResultMatchers.jsonPath("$.id").value(1));
}
@Test
public void testSaveProduct() throws Exception {
Product product = new Product();
product.setId(1);
product.setName("Product name");
product.setPrice(21540.00);
ObjectMapper mapper = new ObjectMapper();
String jsonString = mapper.writeValueAsString(product);
Mockito.when(service.isProductAvailable(Mockito.any(Product.class))).thenReturn(false);
Mockito.doNothing().when(service).saveProduct(Mockito.any(Product.class));
MvcResult result = mockMvc
.perform(MockMvcRequestBuilders.post("/product").content(jsonString)
.contentType(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().is(201)).andReturn();
Assert.assertEquals(201, result.getResponse().getStatus());
}
@Test
public void testUpdateProduct() throws Exception {
Product product = new Product();
product.setId(1);
product.setName("Product name");
product.setPrice(21540.00);
ObjectMapper mapper = new ObjectMapper();
String jsonString = mapper.writeValueAsString(product);
Mockito.when(service.findProductById(Mockito.anyInt())).thenReturn(product);
Mockito.doNothing().when(service).updateProduct(Mockito.any(Product.class));
mockMvc.perform(
MockMvcRequestBuilders.put("/product").content(jsonString).contentType(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().is(200));
}
@Test
public void testDeleteProductByid() throws Exception {
Product product = new Product();
product.setId(1);
product.setName("Product name");
product.setPrice(21540.00);
Mockito.when(service.findProductById(Mockito.anyInt())).thenReturn(product);
Mockito.doNothing().when(service).deleteProductById(Mockito.anyInt());
mockMvc.perform(MockMvcRequestBuilders.delete("/product/1")).andExpect(MockMvcResultMatchers.status().is(200));
}
}
We have used MockitoJunitRunner
to run the Junit test cases. We have mocked the service class and we have used annotation @Spy
and @InjectMocks
on Controller class because we want to call the method of the real object and we want to inject the mocked objects into Controller respectively.
We have also used MockMvc
object, which is a main entry point for server-side Spring MVC test support.
In test case method testGetProductById()
we expect to return only one product from the controller method operation GET
. So we have verified using the mockMvc.perform()
and we don’t need any extra assertion for that.
In the test case method testSaveProduct()
we expect the response status 201
and here we are returning result from mockMvc.perform()
and after that we verifying the status. But if we would not have returned the result from the specified method we could have verified using the same way as we have verified for GET operation.
In test case method testUpdateProduct()
we have tested the PUT
operation and verified the status 200
. Here we could have returned the result from mockMvc.perform()
and verified using assertion but we verified at the same place while we are performing PUT operation using mockMvc.perform()
.
In test case method testDeleteProductByid()
for DELETE
operation we verified the status in the same way as PUT
operation.
Testing Junit
When you run the above Junit test class you will see all tests are passed:

Source Code
Thanks for reading.