一个属性请求在@WebMvcTest 中总是得到 400

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

我有这个控制器端点

@PostMapping("/{productId}/activation/")
    public ResponseEntity<ProductResponse> toggleProductActivation(@PathVariable("productId") UUID productId,
                                                                   @RequestBody @Valid ToggleProductActivationRequest toggleProductActivationRequest)
            throws ApplicationException {
        var product = toggleProductActivationUseCase.handle(productCommandAssembler.assembleToggleProductActivationCommand(
                toggleProductActivationRequest, productId));
        return ResponseEntity.ok()
                             .body(productResponseAssembler.assembleProductResponse(product));
    }

只有一个字段的对应请求POJO

@Builder
@Getter
public class ToggleProductActivationRequest {

    @NotNull
    private Boolean active;
}

最后是我的单元测试

@WebMvcTest(value = ProductAdminController.class)
class ProductAdminControllerTest {

    private static final String EXCEPTION_MESSAGE = "Exception";

    @Autowired
    protected ObjectMapper objectMapper;
    @Autowired
    private MockMvc mockMvc;
    @MockBean
    private ToggleProductActivationUseCase toggleProductActivationUseCase;
    @MockBean
    private ProductCommandAssembler productCommandAssembler;
    @MockBean
    private ProductResponseAssembler productResponseAssembler;

    @Test
    void whenToggleProductActivation_givenProductDoesNotExist_thenReturnNotFound404() throws Exception {
        // given
        var productId = UUID.randomUUID();
        var toggleProductActivationRequest = givenToggleProductActivationRequest();
        var toggleProductActivationCommand = mock(ToggleProductActivationCommand.class);
        when(productCommandAssembler.assembleToggleProductActivationCommand(any(ToggleProductActivationRequest.class),
                                                                            eq(productId),
                                                                            eq(null))).thenReturn(toggleProductActivationCommand);
        when(toggleProductActivationUseCase.handle(toggleProductActivationCommand)).thenThrow(new NotFoundException(
                EXCEPTION_MESSAGE));

        // when & then
        mockMvc.perform(post("/api/v1.0/admin/products/" + productId.toString() + "/activation/")
                                .contentType(MediaType.APPLICATION_JSON)
                                .content(objectMapper.writeValueAsString(toggleProductActivationRequest)))
               .andExpect(status().isNotFound())
               .andExpect(jsonPath("$.httpStatus").value(404))
               .andExpect(jsonPath("$.reason").value(EXCEPTION_MESSAGE));
    }

    private ToggleProductActivationRequest givenToggleProductActivationRequest() {
        return ToggleProductActivationRequest.builder()
                                             .active(true)
                                             .build();
    }
}

运行此测试时,我总是收到 400 Bad Request

为了检查我是否没有让自己发疯,我尝试了这个请求 POJO 我刚刚添加了一个无用的现场测试,这次没有 400,我得到了预期的单元测试结果

@Builder
@Getter
public class ToggleProductActivationRequest {

    @NotNull
    private Boolean active;

    private String test;
}

这里发生了什么。 春季限制?他们为什么要那样做? 错误?那我就举报

你们有什么想法吗?

我可以将激活信息传递给查询参数,但我想保持这种方式

spring-boot spring-mvc mockmvc
1个回答
0
投票

我才发现问题出在龙目岛这边:

我必须添加所有构造函数

@Builder
@Getter
@AllArgsConstructor
@NoArgsConstructor
public class ToggleProductActivationRequest {

    @NotNull
    private Boolean active;
}

当我在 POJO 中有超过 1 个属性时,不需要这样做

© www.soinside.com 2019 - 2024. All rights reserved.