Reputation: 23
I am trying to mock my controller and write testcases for it. But when I tried to debug the Test class the control is not getting into my Controller class. I am not sure what I am doing wrong here.
Please help me to resolve this as I am stuck on this for almost more that 3 hours.
My Service class
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.bnpp.leavemanagement.dao.DepartmentRepository;
import com.bnpp.leavemanagement.model.DepartmentModel;
@Service
public class DepartmentService
{
@Autowired
DepartmentRepository depRepo;
public List<DepartmentModel> listDepartment = new ArrayList<>();
public List<DepartmentModel> getAllDepartments()
{
List<DepartmentModel> allDepartment = depRepo.findAll();
return allDepartment;
}
public DepartmentModel fetchDepartmentById( int id)
{
DepartmentModel depDetail = null;
try
{
depDetail = depRepo.findById(Long.valueOf(id)).get();
}
catch(Exception ex)
{
depDetail = null;
}
return depDetail;
}
public DepartmentModel addDepartment(DepartmentModel depDetail)
{
DepartmentModel depExists = null;
if (listDepartment.size() > 0)
{
depExists = listDepartment.stream()
.filter(d -> d.getName().equalsIgnoreCase(depDetail.getName()))
.findFirst()
.orElse(null);
}
//Below condition is to restrict duplicate department creation
if(depExists == null)
{
depRepo.save(depDetail);
listDepartment.add(depDetail);
}
else
{
return null;
}
return depDetail;
}
public DepartmentModel updateDepartment(DepartmentModel depDetail)
{
DepartmentModel depUpdate = null;
try
{
depUpdate = depRepo.findById(depDetail.getId()).get();
depUpdate.setName(depDetail.getName());
depRepo.save(depUpdate);
}
catch(Exception ex)
{
depUpdate = null;
}
return depUpdate;
}
public DepartmentModel deleteDepartment(DepartmentModel depDetail)
{
try
{
depRepo.deleteById(depDetail.getId());
}
catch(Exception ex)
{
return null;
}
return depDetail;
}
}
My Test Class
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.util.ArrayList;
import java.util.List;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
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.context.annotation.Description;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.web.WebAppConfiguration;
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.web.context.WebApplicationContext;
import com.bnpp.leavemanagement.controller.DepartmentController;
import com.bnpp.leavemanagement.model.DepartmentModel;
import com.bnpp.leavemanagement.service.DepartmentService;
@ExtendWith(MockitoExtension.class)
@WebMvcTest(DepartmentController.class)
@ContextConfiguration(classes = com.bnpp.leavemanagementsystem.LeaveManagementSystemApplicationTests.class)
public class DepartmentControllerTest {
@MockBean
DepartmentService depService;
@Autowired
private MockMvc mockMvc;
@InjectMocks
DepartmentController departmentController;
@Autowired
private WebApplicationContext webApplicationContext;
@Test
@Description("Should return a list of DepartmentModel objects when called")
void shouldReturnListOfDepartmentModel() throws Exception
{
DepartmentModel depModel = new DepartmentModel();
depModel.setId(1L);
depModel.setName("Mock");
List<DepartmentModel> listDepmodel = new ArrayList<>();
listDepmodel.add(depModel);
Mockito.when(depService.getAllDepartments()).thenReturn(listDepmodel);
mockMvc.perform(MockMvcRequestBuilders.get("/department"))
.andDo(print())
.andExpect(status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$.size()", Matchers.is(1)))
.andExpect(MockMvcResultMatchers.jsonPath("$[0].id").value(1))
.andExpect(MockMvcResultMatchers.jsonPath("$[0].name").value("Mock"));
}
}
My Controller class
package com.bnpp.leavemanagement.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.bnpp.leavemanagement.dao.DepartmentRepository;
import com.bnpp.leavemanagement.model.DepartmentModel;
import com.bnpp.leavemanagement.service.DepartmentService;
@RestController
public class DepartmentController
{
@Autowired
DepartmentService depService;
@GetMapping("/department")
public ResponseEntity<List<DepartmentModel>> getDepartments()
{
List<DepartmentModel> allDepartment = depService.getAllDepartments();
if(allDepartment.size() == 0)
{
return new ResponseEntity( HttpStatus.NOT_FOUND);
}
return new ResponseEntity( allDepartment, HttpStatus.OK);
}
@GetMapping("/department/{id}")
public ResponseEntity<DepartmentModel> fetchDepartmentById(@PathVariable("id") int id)
{
DepartmentModel resDep = depService.fetchDepartmentById(id);
if(resDep == null)
{
return new ResponseEntity(HttpStatus.NOT_FOUND);
}
else
{
return new ResponseEntity( resDep, HttpStatus.OK);
}
}
@PostMapping("/department/create")
public ResponseEntity<DepartmentModel> createDepartment(@RequestBody DepartmentModel depNew)
{
DepartmentModel resDep = depService.addDepartment(depNew);
if(resDep == null)
{
return new ResponseEntity(HttpStatus.EXPECTATION_FAILED);
}
else
{
return new ResponseEntity( resDep, HttpStatus.CREATED);
}
}
@PutMapping("/department/update")
public ResponseEntity<DepartmentModel> updateDepartment(@RequestBody DepartmentModel depNew)
{
DepartmentModel resDep = depService.updateDepartment(depNew);
if(resDep == null)
{
return new ResponseEntity(HttpStatus.NOT_FOUND);
}
else
{
return new ResponseEntity( resDep, HttpStatus.OK);
}
}
@DeleteMapping("/department/delete")
public ResponseEntity<DepartmentModel> deleteDepartment(@RequestBody DepartmentModel depDel)
{
DepartmentModel resDep = depService.deleteDepartment(depDel);
if(resDep == null)
{
return new ResponseEntity(HttpStatus.NOT_FOUND);
}
else
{
return new ResponseEntity(HttpStatus.OK);
}
}
}
Upvotes: 1
Views: 1208
Reputation: 12021
The minimal viable test setup to use MockMvc
with @WebMvcTest
is the following:
@WebMvcTest(DepartmentController.class)
class DepartmentControllerTest {
@MockBean
DepartmentService depService;
@Autowired
private MockMvc mockMvc;
@Test
@Description("Should return a list of DepartmentModel objects when called")
void shouldReturnListOfDepartmentModel() throws Exception {
DepartmentModel depModel = new DepartmentModel();
depModel.setId(1L);
depModel.setName("Mock");
List<DepartmentModel> listDepmodel = new ArrayList<>();
listDepmodel.add(depModel);
Mockito.when(depService.getAllDepartments()).thenReturn(listDepmodel);
mockMvc.perform(MockMvcRequestBuilders.get("/department"))
.andDo(print())
.andExpect(status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$.size()", Matchers.is(1)))
.andExpect(MockMvcResultMatchers.jsonPath("$[0].id").value(1))
.andExpect(MockMvcResultMatchers.jsonPath("$[0].name").value("Mock"));
}
}
Explanation:
@InjectMocks
is not necessary as with @MockBean
you're adding a mocked version of DepartmentService
to your Spring TestContext and Spring DI's mechanism will inject it to your DepartmentController
@ExtendWith(SpringExtension.class)
is also redundant, as the meta annotation @WebMvcTest
already activates the SpringExtension.class
You don't need @ContextConfiguration
here as @WebMvcTest
takes care to detect your Spring Boot entrypoint class and start a sliced context
If the test still doesn't work, please add all your dependencies, the way you structure your code, and your main Spring Boot class (annotated with @SpringBootApplication
).
Further reads that might shed some light on this:
Upvotes: 0