微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

我的控制器代码无法从 MockMvc get 请求访问,我总是收到 404

如何解决我的控制器代码无法从 MockMvc get 请求访问,我总是收到 404

我正在尝试模拟我的控制器并为其编写测试用例。但是当我尝试调试 Test 类时,控件没有进入我的 Controller 类。我不确定我在这里做错了什么。

请帮我解决这个问题,因为我在这个问题上停留了将近 3 个小时。

我的服务类


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;
    }
    
}

我的测试班


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"));
    }

}

我的控制器类

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);
        }
    }
    
}
 

解决方法

使用 MockMvc@WebMvcTest 的最小可行测试设置如下:

@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"));
    }
}

说明:

  • @InjectMocks 不是必需的,因为 @MockBean 您正在将 DepartmentService 的模拟版本添加到您的 Spring TestContext 并且 Spring DI 的机制会将其注入您的 {{1 }}

  • DepartmentController 也是多余的,因为元注释 @ExtendWith(SpringExtension.class) 已经激活了 @WebMvcTest

  • 此处不需要 SpringExtension.class,因为 @ContextConfiguration 会注意检测您的 Spring Boot 入口点类并启动切片上下文

如果测试仍然不起作用,请添加您的所有依赖项、您构建代码的方式以及您的主要 Spring Boot 类(用 @WebMvcTest 注释)。

进一步阅读可能会对此有所了解:

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。