@SpringBootTest annotation

The @SpringBootTest annotation provides the functionality to bootstrap the entire container. It loads entire application context for Spring Boot application and create integration test.

Usually, we write unit test cases for all methods of a class such as a test case class for one Controller, 2nd test case class for 2nd Controller or one test case class for a Service class and 2nd test case class for 2nd Service class.

But, another option is also available. if you declare the @SpringBootTest annotation, you can write test cases for entire flow in one test case class such as you can write the test cases for Controller and Service integration logic in the same method/class.

---@SpringBootTest Annotation Example---
@SpringBootTest
class public MainClassApplicationTests {
 
  @Test
  void contextLoads() {
    //write your test here
  }
}

@WebMvcTest annotation in Spring Boot Mockito Junit

The @WebMvcTest annotation provides the functionality of disabling full auto-configuration and instead of full auto-configuration provides only configuration relevant to MVC tests.

If we declare @WebMvcTest(controllers = UserController.class) that means we are asking to initialize only one web controller(UserController.class). We need to provide the remaining dependencies required using Mock objects.

---@WebMvcTest Annotation Example---
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.web.servlet.MockMvc;

@WebMvcTest(controllers =  UserController.class)
public class UserControllerTest {
    
    @Autowired
    MockMvc mockMvc;
}

@ExtendWith annotation in Spring Boot Mockito Junit

The @ExtendWith annotation in JUnit 5 is used to register extensions. Mockito provides the MockitoExtension class that can be used with the @ExtendWith annotation to enable Mockito annotations and simplify the creation of mocks.

You can not use @ExtendWith annotation in JUnit 4. If you are using older than JUnit 5 then need to use @RunWith annotation instead of @ExtendWith annotation.

The @ExtendWith annotation can receive an array of extensions allowing many of them to be used in the same test. Something like this @ExtendWith({MockitoExtension.class, LogAsserterExtension.class}).

---@ExtendWith Annotation Example---
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.web.servlet.MockMvc;

@WebMvcTest(controllers =  UserController.class)
@ExtendWith(MockitoExtension.class, LogAsserterExtension.class)
public class UserControllerTest {
    
    @Autowired
    MockMvc mockMvc;
}

MockMvc in Spring Boot Mockito Junit

The MockMvc provides the functionality of unit testing for the controller classes in the Spring MVC applications. It is also used for testing the entire MVC stack, including controllers, filters, and other MVC components.

We can perform and test of the HTTP requests like GET, POST, PUT, DELETE and validate the response by using The MockMvc.

---MockMvc Example---
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.web.servlet.MockMvc;

@WebMvcTest(controllers =  UserController.class)
@ExtendWith(MockitoExtension.class, LogAsserterExtension.class)
public class UserControllerTest {
    
    @Autowired
    MockMvc mockMvc;
}

@MockBean Annotation in Spring Boot Mockito Junit

The @MockBean annotation is provided by Spring library( org.springframework.boot.test.mock.mockito.MockBean). @MockBean annotation add mock bean objects to the Spring application context. The @MockBean can be used field level or class level in the unit test cases.

If the bean object already exists in the Spring application context it will be replace with new bean object.

If the bean object not exist in the Spring application context it willcreate a new bean object and add into application context.

---MockMvc Example---
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.boot.test.mock.mockito.MockBean;


@WebMvcTest(controllers =  UserController.class)
@ExtendWith(MockitoExtension.class, LogAsserterExtension.class)
public class UserControllerTest {
    
    @Autowired
    MockMvc mockMvc;

    @MockBean
    UserService userService;

}

Different between @Mock and @MockBean Annotation.

The @Mock annotation provided by Mockito libraty. (org.mockito.Mock) while The @MockBean annotation is provided by Spring library( org.springframework.boot.test.mock.mockito.MockBean). The @Mock annotation does not add the mock bean objects to the Spring application context while @MockBean add the mock bean object into the Spring application context.

If the Spring application context is available and bean object already exists then you can use @MockBean.

If the Spring application context is not available then you can use the @Mock annotation to create a mock bean.

---MockMvc Example---
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.web.servlet.MockMvc;
import org.mockito.Mock;
import org.springframework.boot.test.mock.mockito.MockBean;

@WebMvcTest(controllers =  UserController.class)
@ExtendWith(MockitoExtension.class, LogAsserterExtension.class)
public class UserControllerTest {
    
    @Autowired
    MockMvc mockMvc;

    @MockBean
    UserService userService;
    ---or---
    @Mock
    UserService userService;
}

@InjectMock Annotation in Mockito Junit

The @InjectMock annotation is used to create the mock bean object of the field level dependency of the class which annotated with @Mock or @MockBean. It provides the mock bean of field level dependency.

Suppose, The mock object of the UserService class created in the test class and UserService class annotated the @Mock or @MockBean.
@Mock
UserService userService;

If the UserService class has dependency with repository like below code then you need to use @InjectMock to create mock bean object of the repository class.
@Service
public class UserService {

  @Autowired
  UserRepository userRepository;
}

---MockMvc Example---
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.web.servlet.MockMvc;
import org.mockito.Mock;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.mockito.InjectMocks;

@WebMvcTest(controllers =  UserController.class)
@ExtendWith(MockitoExtension.class, LogAsserterExtension.class)
public class UserControllerTest {
    
    @Autowired
    MockMvc mockMvc;
   
    @Mock
    UserService userService;

    @InjectMock
    UserRepository userRepository;
}

@BeforeTestClass and @AfterTestClass Annotation in Mockito Junit

The @BeforeTestClass annotation provide the functionality to execute the method before executing the test cases.

The @AfterTestClass annotation provide the functionality to execute the method after completion of all the test cases.

---MockMvc Example---
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.context.event.annotation.AfterTestClass;
import org.springframework.test.context.event.annotation.BeforeTestClass;

@WebMvcTest(controllers =  UserController.class)
@ExtendWith(MockitoExtension.class, LogAsserterExtension.class)
public class UserControllerTest {
    
    @BeforeTestClass
    public void befor(){
        System.out.println("BeforeTestClass");
    }

    @AfterTestClass
    public void after(){
        System.out.println("AfterTestClass");
    }
}

@BeforeEach Annotation in Mockito Junit

The @BeforeEach annotation provides the functionality to execute before each test method in the JUnit test case. It is used to provide initialization for set-up tasks.

---MockMvc Example---
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.web.servlet.MockMvc;
import org.mockito.Mock;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.mockito.InjectMocks;

@WebMvcTest(controllers =  UserController.class)
@ExtendWith(MockitoExtension.class, LogAsserterExtension.class)
public class UserControllerTest {
    
    @Autowired
    MockMvc mockMvc;
    
    @Mock
    UserService userService;

    @InjectMock
    UserRepository userRepository;

    @BeforeEach
    public void init(){
        user = getMockUser();
        userDTO = getMockUserDTO();
    }

    @test
    /......

}

Rest Controller Test Cases in Spring Boot Mockito

Rest Controller Test Cases in Spring Boot Mockito Example

import com.fasterxml.jackson.databind.ObjectMapper; import org.hamcrest.CoreMatchers; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockMultipartFile; import org.springframework.test.web.servlet.MockMvc; import org.mockito.ArgumentMatchers; import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.result.MockMvcResultMatchers; import java.io.InputStream; import java.util.ArrayList; import java.util.List; @WebMvcTest(controllers = UserController.class) @ExtendWith(MockitoExtension.class, LogAsserterExtension.class) public class UserControllerTest { @Autowired MockMvc mockMvc; @Mock UserService userService; private User user; private UserDTO userDTO; @BeforeEach public void init(){ user = getMockUser(); userDTO = getMockUserDTO(); } private User getMockUser(){ if(user!=null){ return user; }else { user = new User(); user.setId(1); user.setName("Shib Das"); user.setMobileNumber("8650932"); user.setEmailId("s@gmail.com"); user.setAddress("Pune, India"); return user; } } private UserDTO getMockUserDTO(){ if(userDTO!=null){ return userDTO; }else { userDTO = new UserDTO(); userDTO.setId(user.getId()); userDTO.setName(user.getName()); userDTO.setMobileNumber(user.getMobileNumber()); userDTO.setEmailId(user.getEmailId()); userDTO.setAddress(user.getAddress()); return new UserDTO(); } }

Rest Controller GET Method Test Cases in Spring Boot Mockito

@Test void getUserById() throws Exception { given(userService.findUserById(any())).willReturn(userDTO); ResultActions response = mockMvc.perform(get("/user/get/1") .contentType(MediaType.APPLICATION_JSON)); response.andExpect(status().isOk()) .andExpect(MockMvcResultMatchers.jsonPath( "$.id", CoreMatchers.is( userDTO.getId()))) .andExpect(MockMvcResultMatchers.jsonPath( "$.name", CoreMatchers.is( userDTO.getName()))) .andExpect(MockMvcResultMatchers.jsonPath( "$.mobileNumber", CoreMatchers.is( userDTO.getMobileNumber()))) .andExpect(MockMvcResultMatchers.jsonPath( "$.emailId", CoreMatchers.is( userDTO.getEmailId()))) .andExpect(MockMvcResultMatchers.jsonPath( "$.address", CoreMatchers.is( userDTO.getAddress()))); }

Rest Controller GET All Test Cases in Spring Boot Mockito

@Test void testGetAll() throws Exception { UserDTO userDTO1 = new UserDTO(1,"Shib Das","s@gmail.com","8650932","pune"); List userList = new ArrayList(); userList.add(userDTO1); userList.add(userDTO1); AllUserDTO allUserDTO = new AllUserDTO(); allUserDTO.setUserList(userList); given(userService.getAllUser()).willReturn(allUserDTO); ResultActions response = mockMvc.perform(get( "/user/getall") .contentType( MediaType.APPLICATION_JSON)); response.andExpect( MockMvcResultMatchers.status().isOk() ).andDo(print()) .andExpect(MockMvcResultMatchers.jsonPath( "$.userList", hasSize(2))) .andExpect(MockMvcResultMatchers.jsonPath( "$.userList[0].id", CoreMatchers.is( 1 ))) .andExpect(MockMvcResultMatchers.jsonPath( "$.userList[0].name", CoreMatchers.is( "Shib Das" ))) .andExpect(MockMvcResultMatchers.jsonPath( "$.userList[0].emailId", CoreMatchers.is( "s@gmail.com" ))) .andExpect(MockMvcResultMatchers.jsonPath( "$.userList[0].address", CoreMatchers.is( "pune" ))) .andExpect(MockMvcResultMatchers.jsonPath( "$.userList[0].mobileNumber", CoreMatchers.is( "8650932" ))); }

Rest Controller POST Method Test Cases in Spring Boot Mockito

@Test void addTest() throws Exception { given(userService.addUser(ArgumentMatchers.any())).willAnswer(invocation -> invocation.getArgument(0)); //or when(userService.addUser(any())).thenReturn(getMockUserDTO()); ResultActions response = mockMvc.perform(post( "/user/add" ) .contentType(MediaType.APPLICATION_JSON) .content( objectMapper.writeValueAsString( userDTO ))); response.andExpect(status().isOk()) .andExpect(MockMvcResultMatchers.jsonPath( "$.id", CoreMatchers.is( userDTO.getId() ))) .andExpect(MockMvcResultMatchers.jsonPath( "$.name", CoreMatchers.is( userDTO.getName() ))) .andExpect(MockMvcResultMatchers.jsonPath( "$.mobileNumber", CoreMatchers.is( userDTO.getMobileNumber() ))) .andExpect(MockMvcResultMatchers.jsonPath( "$.emailId", CoreMatchers.is( userDTO.getEmailId() ))) .andExpect(MockMvcResultMatchers.jsonPath( "$.address", CoreMatchers.is( userDTO.getAddress() ))); }

Rest Controller PUT Method Test Cases in Spring Boot Mockito

@Test void updateTest() throws Exception { System.out.println("getUserById--"); given(userService.update(any())).willReturn(userDTO); ResultActions response = mockMvc.perform( put( "/user/update" ) .contentType(MediaType.APPLICATION_JSON) .content( objectMapper.writeValueAsString( userDTO ))); response.andExpect(status().isOk()) .andExpect(MockMvcResultMatchers.jsonPath( "$.id", CoreMatchers.is( userDTO.getId() ))) .andExpect(MockMvcResultMatchers.jsonPath( "$.name", CoreMatchers.is( userDTO.getName() ))) .andExpect(MockMvcResultMatchers.jsonPath( "$.mobileNumber", CoreMatchers.is( userDTO.getMobileNumber() ))) .andExpect(MockMvcResultMatchers.jsonPath( "$.emailId", CoreMatchers.is( userDTO.getEmailId() ))) .andExpect(MockMvcResultMatchers.jsonPath( "$.address", CoreMatchers.is( userDTO.getAddress() ))); }

Rest Controller DELETE Method Test Cases in Spring Boot Mockito

@Test void testDelete() throws Exception { given(userService.delete(1)).willReturn( "Employee deleted" ); ResultActions response = mockMvc.perform(delete( "/user/delete/1" ) .contentType( MediaType.APPLICATION_JSON )); response.andExpect( MockMvcResultMatchers.status().isOk()) .andExpect( MockMvcResultMatchers.content().string( "Employee deleted" )); }

Rest Controller multipart or File Upload Test Cases in Spring Boot Mockito

@Test public void testFileUpload() throws Exception { InputStream inputStream = UserControllerTest.class. getClassLoader().getResourceAsStream( "users.csv" ); MockMultipartFile file = new MockMultipartFile( "file", inputStream ); FileUploadResponse fileUploadResponse = new FileUploadResponse( "users.csv", "Success", 5 ); given(userService.fileUpload( ArgumentMatchers.any() )).willReturn( fileUploadResponse ); assertNotNull( inputStream ); ResultActions response = mockMvc.perform( MockMvcRequestBuilders.multipart( "/user/fileupload" ).file(file).param( "name", "user.csv" )); response.andExpect(MockMvcResultMatchers.status().isOk()) .andExpect(MockMvcResultMatchers.jsonPath( "$.fileName", CoreMatchers.is( "users.csv" ))) .andExpect(MockMvcResultMatchers.jsonPath( "$.status", CoreMatchers.is( "Success" ))) .andExpect(MockMvcResultMatchers.jsonPath( "$.count", CoreMatchers.is( 5 ))); }

Rest Controller File Download Test Cases in Spring Boot Mockito

@Test public void testFileDownload() throws Exception { String fileDownloadContent = "Shib Das, s@gmail.com, 90764, Pune India Maharastra\r\n" + "Shib Das1, s@gmail.com, 90764, Pune India Maharastra\r\n" + "Shib Das2, s@gmail.com, 90764, Pune India Maharastra\r\n" + "Shib Das3, s@gmail.com, 90764, Pune India Maharastra\r\n" + "Shib Das4, s@gmail.com, 90764, Pune India Maharastra"; InputStream inputStream = UserControllerTest.class .getClassLoader().getResourceAsStream( "users.csv" ); MockMultipartFile file = new MockMultipartFile( "file", inputStream ); MvcResult result = mockMvc.perform(get( "/user/filedownload/users.csv" ) .contentType( MediaType.APPLICATION_JSON )).andReturn(); MockHttpServletResponse response = result.getResponse(); assertThat( response.getStatus()).isEqualTo( HttpStatus.OK.value() ); assertThat( response.getContentType()).isEqualTo( "application/CSV" ); assertThat( response.getContentAsString().trim()).isEqualTo( fileDownloadContent.trim() ); assertThat( response.getContentAsByteArray()).isEqualTo( file.getBytes() ); }

Rest Controller Exception Test Cases in Spring Boot Mockito

@Test void testDeleteErrorMessage() throws Exception { given(userService.delete(1)).willThrow( new Exception( "Error: User with id does not exist" )); Exception thrown = assertThrows( Exception.class, () -> mockMvc.perform(delete("/user/delete/1") .contentType(MediaType.APPLICATION_JSON)), "Expected to throw, but it didn't" ); assertTrue( thrown.getMessage().contains( "Error: User with id does not exist" )); } //2nd example @Test void testUpdateForErrorMessage() throws Exception { given(userService.update(ArgumentMatchers.any())).willThrow( new Exception( "Error: User with id does not exist" )); Exception thrown = assertThrows( Exception.class, () -> mockMvc.perform( put("/user/update" ) .contentType( MediaType.APPLICATION_JSON ) .content( objectMapper.writeValueAsString(userDTO) )), "Expected to throw, but it didn't" ); assertTrue( thrown.getMessage().contains( "Error: User with id does not exist" )); }
}