在Spring Boot REST控制器测试期间未触发语句时模拟

问题描述 投票:0回答:1

我已经编写了一个典型的三层Spring Boot REST API,并正在为此进行测试。 API本身运行良好,但是我遇到了使控制器测试正常工作的问题。返回的主体为空,因为控制器层返回的对象为null。这是游戏中的主要依赖项。

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.12.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>  

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-test</artifactId>
    <scope>test</scope>
</dependency>

我已经嘲笑了服务层,但是测试中的when语句似乎并没有按照我的预期触发。

这里是测试本身:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
@AutoConfigureMockMvc
public class VehicleControllerTest {

    @MockBean
    VehicleServiceImpl vService;

    @Mock
    HttpServletRequest mockRequest;

    @Mock
    Principal mockPrincipal;

    @Autowired
    MockMvc mockMvc;

    Vehicle vehicle1;

    @BeforeEach
    public void setUp() throws ItemNotFoundException {

        vehicle1 = new Vehicle();
        vehicle1.setVin("5YJ3E1EA5KF328931");
        vehicle1.setColor("black");
        vehicle1.setDisplayName("Black Car");
        vehicle1.setId(1L);
    }

    @Test
    @WithMockUser("USER")
    public void findVehicleByIdSuccess() throws Exception {

        //Given **I think the problem is here***
        when(vService.findVehicleById(any(),any(),any())).thenReturn(vehicle1);

        //When
        this.mockMvc.perform(get("/vehicles/1")).andDo(print())

        //Then
        .andExpect(status().isOk());
    }
}

以下是相应的控制器方法:

@Secured("ROLE_USER")
public class VehicleController {


    @JsonView(VehicleView.summary.class)
    @GetMapping("/vehicles/{id}")
    public Vehicle findVehicleById(@PathVariable Long id, Principal principal,
                                   HttpServletRequest request) throws ItemNotFoundException {

        log.info("In controller " +LogFormat.urlLogFormat(request,principal.getName()));       
        return vehicleService.findVehicleById(id,principal, request);
     }

这里是MockHTTPServletResponse。状态为200,但主体为空

MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = [X-Content-Type-Options:"nosniff", X-XSS-Protection:"1; mode=block", Cache-Control:"no-cache, no-store, max-age=0, must-revalidate", Pragma:"no-cache", Expires:"0", X-Frame-Options:"DENY"]
     Content type = null
             Body = 
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

供参考,这是我尝试模拟的服务方法

    @Override
    public Vehicle findVehicleById(Long id, Principal principal, HttpServletRequest request) throws ItemNotFoundException {

        Optional<Vehicle> vehicle = vehicleRepository.findByIdAndUserId(id,principal.getName());     

        if (vehicle.isPresent()){
            return vehicle.get();
        } else {
            throw new ItemNotFoundException(id,"vehicle");
        }
    }

我尝试过不同版本的Springboot,但这没有帮助。我开始使用2.2.4,但是我认为我会尝试2.1.X火车,因为它已经存在了很长时间。由于我得到的日志输出,我可以确认正在调用控制器中的正确方法。

spring-boot spring-security spring-restcontroller spring-test-mvc
1个回答
0
投票

您确实模拟了服务对象,但没有将其注入到控制器中。

@InjectMocks
private VehicleController vehicleController = new VehicleController();

使用MockitoAnnotations.initMocks(this)初始化这些模拟对象,而不是自动装配MockMvc对象,而是像这样通过控制器来传递它:

@BeforeEach
void setup() {
    MockitoAnnotations.initMocks(this);

    this.mockMvc = MockMvcBuilders.standaloneSetup(vehicleController).build();
© www.soinside.com 2019 - 2024. All rights reserved.