text:
Q: My controller code is not reachable from the MockMvc get request and i am always getting 404 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);
        }
    }

}

A: 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:

*

*Difference Between @Mock and @MockBean

*Guide to Testing Spring Boot Applications With MockMvc


Slippery conditions are an inevitable part of every winter. Ice cleats have become a popular method for reducing winter slips and falls; but how do you choose which ice cleat will serve you best?
Unlike other safety categories like steel toes or hard hats, winter slips and falls do not have any industry standards for safety professionals to follow. This means that the onus of choosing the right product, style, brand, etc. falls entirely on the safety team. And with literally hundreds of ice cleat options on the web all claiming to be the best, how do you decide which ice cleat is right for you?
Join us for a presentation on preventing winter slips and falls. Learn the two most important criteria you should consider when selecting an ice walking product. Hear the five most common mistakes of a failed slip and fall program. Hear why a good slip and fall program relies on more than just a good ice cleat. And understand why there is no silver bullet solution as well as suggestions on how to get even your most stubborn employee interested in wearing ice cleats this winter. 60 minutes of education for a season's worth of safety!
Formerly known as Jordan David, Winter Walking has been North America's largest manufacturer of All Traction Footwear for over 35 years. For more than ten years Jordan has been focused on helping companies of all sizes and industries reduce their winter slips and falls. With numerous patents to his name, Jordan is also hands on in the creation and design of each ice cleat manufactured by Winter Walking.