In this tutorial, we are going to write JUnit test cases for the Spring Boot controller.
Spring MVC test framework provides MockMvc class to test the controllers by initiating the Servlet container.
Spring Boot MockMvc JUnit Test:
Here I am going to write unit test cases for our previous Spring Boot Exception Handling Example.
Technologies:
- Spring Boot 2.0.4
- Spring Boot Starter Test 2.0.4
- JUnit 4.12
- Java8
Application Dependencies:
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Rest Controller:
A simple rest controller which provides all crud operations on ItemRepoitory.
ItemController.java
package com.onlinetutorialspoint.controller;
import com.onlinetutorialspoint.exception.ItemNotFoundException;
import com.onlinetutorialspoint.model.Item;
import com.onlinetutorialspoint.repo.ItemRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
public class ItemController {
@Autowired
ItemRepository itemRepo;
@RequestMapping("/getAllItems")
@ResponseBody
public ResponseEntity<List<Item>> getAllItems(){
List<Item> items = itemRepo.getAllItems();
return new ResponseEntity<List<Item>>(items, HttpStatus.OK);
}
@GetMapping("/item/{itemId}")
@ResponseBody
public ResponseEntity<Item> getItem(@PathVariable int itemId){
if(itemId <= 0){
throw new ItemNotFoundException("Invalid ItemId");
}
Item item = itemRepo.getItem(itemId);
return new ResponseEntity<Item>(item, HttpStatus.OK);
}
@PostMapping(value = "/addItem",consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Item> addItem(@RequestBody Item item){
itemRepo.addItem(item);
return new ResponseEntity<Item>(item, HttpStatus.CREATED);
}
@PutMapping("/updateItem")
@ResponseBody
public ResponseEntity<Item> updateItem(@RequestBody Item item){
if(item != null){
itemRepo.updateItem(item);
}
return new ResponseEntity<Item>(item, HttpStatus.OK);
}
@DeleteMapping("/delete/{id}")
@ResponseBody
public ResponseEntity<Void> deleteItem(@PathVariable int id){
itemRepo.deleteItem(id);
return new ResponseEntity<Void>(HttpStatus.ACCEPTED);
}
}
Spring Boot MockMvc JUnit:
Creating ItemControllerTest to perform all test cases against ItemController class.
ItemControllerTest.java
package com.onlinetutorialspoint.controller;
import com.onlinetutorialspoint.model.Item;
import com.onlinetutorialspoint.repo.ItemRepository;
import org.hamcrest.Matchers;
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.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
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 java.util.Arrays;
import java.util.List;
@RunWith(SpringRunner.class)
public class ItemControllerTest {
private MockMvc mockMvc;
@InjectMocks
ItemController itemController;
@Mock
ItemRepository itemRepository;
@Before
public void setUp(){
mockMvc = MockMvcBuilders.standaloneSetup(itemController)
.build();
}
@Test
public void getAllItems() throws Exception {
List<Item> items = Arrays.asList(new Item(1,"iPhoneX","Mobiles"));
Mockito.when(itemRepository.getAllItems()).thenReturn(items);
mockMvc.perform(MockMvcRequestBuilders.get("/getAllItems"))
.andExpect(MockMvcResultMatchers.status().isOk());
}
@Test
public void getItem() throws Exception{
Item item = new Item(1,"iPhoneX","Mobiles");
Mockito.when(itemRepository.getItem(1)).thenReturn(item);
mockMvc.perform(MockMvcRequestBuilders.get("/item/1")
.accept(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$.id", Matchers.is(1)))
.andExpect(MockMvcResultMatchers.jsonPath("$.name",Matchers.is("iPhoneX")))
.andExpect(MockMvcResultMatchers.jsonPath("$.category",Matchers.is("Mobiles")));
Mockito.verify(itemRepository).getItem(1);
}
@Test
public void addItem() throws Exception {
String jsonString = "{\n" +
"\"id\":1,\n" +
"\"name\":\"iPhoneX\",\n" +
"\"category\":\"Mobiles\"\n" +
"}";
Item item = new Item(1,"iPhoneX","Mobiles");
mockMvc.perform(MockMvcRequestBuilders.post("/addItem")
.contentType(MediaType.APPLICATION_JSON)
.content(jsonString))
.andExpect(MockMvcResultMatchers.status().isCreated())
.andExpect(MockMvcResultMatchers.jsonPath("$.id", Matchers.is(1)))
.andExpect(MockMvcResultMatchers.jsonPath("$.name",Matchers.is("iPhoneX")))
.andExpect(MockMvcResultMatchers.jsonPath("$.category",Matchers.is("Mobiles")));
}
@Test
public void updateItem() throws Exception {
String jsonString = "{\n" +
"\"id\":1,\n" +
"\"name\":\"iPhoneX\",\n" +
"\"category\":\"Mobiles\"\n" +
"}";
Item item = new Item(1,"iPhoneX","Mobiles");
mockMvc.perform(MockMvcRequestBuilders.put("/updateItem")
.contentType(MediaType.APPLICATION_JSON)
.content(jsonString))
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$.id", Matchers.is(1)))
.andExpect(MockMvcResultMatchers.jsonPath("$.name",Matchers.is("iPhoneX")))
.andExpect(MockMvcResultMatchers.jsonPath("$.category",Matchers.is("Mobiles")));
}
@Test
public void deleteItem() throws Exception{
mockMvc.perform(MockMvcRequestBuilders.delete("/delete/1")
.accept(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().isAccepted());
}
}
Run It.
References:
Happy Learning 🙂