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.

The complete Junit class is given below

package jeejava.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 jeejava.model.Product;
import jeejava.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.

Thanks for reading.

 

Tags:

I am a professional Web developer, Enterprise Application developer, Software Engineer and Blogger. Connect me on Roy Tutorials | TwitterFacebook Google PlusLinkedin | Reddit | Email Me

Leave a Reply

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