Spring MVC (Sping Boot )未验证记录中记录的字段(由@RequestBody注解)

mutmk8jj  于 8个月前  发布在  Spring
关注(0)|答案(1)|浏览(72)

我正在构建一个Sping Boot 应用程序,并正在使用**@WebMvcTest测试我的控制器。
我有一个控制器方法,它接受
@Validated @RequestBody*UpdateFoodReqBody**(record),其中有一个字段**@Validated @ NothingUpdateProductReqBody**(record),我也想验证它。
当产品对象为空时,测试有效,但当产品存在但其字段无效时,测试无效。

@PostMapping("/update-food/{foodId}")
public GetFoodResponse updateFood(
        @PathVariable @NotNull Long foodId,
        @Validated @RequestBody UpdateFoodReqBody updatedFood) {
    return foodService.updateFood(foodId, updatedFood);
}
public record UpdateFoodReqBody(
        String dietaryRestrictions,
        @Validated @NotNull UpdateProductReqBody product
) {
}
@Validated
public record UpdateProductReqBody(
        @NotBlank String name,
        String description,
        @NotNull @Positive BigDecimal price,
        @NotNull Date pickupTime
) {
}

测试成功:

@Test
public void testUpdateFood_invalidInput_forStackOverflow() throws Exception {
    mockMvc.perform(MockMvcRequestBuilders
                    .post(controllerPath + "/update-food/1")
                    .accept(MediaType.APPLICATION_JSON)
                    .content(objectMapper.writeValueAsString(
                            new UpdateFoodReqBody("Restrictions", null)))
                    .contentType("application/json"))
            .andExpect(result -> assertTrue(result.getResolvedException() instanceof MethodArgumentNotValidException))
            .andExpect(status().isBadRequest());
}

Test succesful!

**测试失败(...已解决异常:Type = null... ):

@Test
public void testUpdateFood_invalidInput_forStackOverflow() throws Exception {
    mockMvc.perform(MockMvcRequestBuilders
                    .post(controllerPath + "/update-food/1")
                    .accept(MediaType.APPLICATION_JSON)
                    .content(objectMapper.writeValueAsString(
                            new UpdateFoodReqBody(
                                    "Restrictions",
                                    new UpdateProductReqBody(null, "Description", null, new Date()))
                    ))
                    .contentType("application/json"))
            .andExpect(result -> assertTrue(result.getResolvedException() instanceof MethodArgumentNotValidException))
            .andExpect(status().isBadRequest());
}

Causes:
Resolved Exception:
             Type = null

起初我只在控制器类中有@Validated注解。有问题所以也添加了@Validated到记录本身,没有区别
有人能给点建议吗。谢谢!

rbl8hiat

rbl8hiat1#

好吧,我自己解决了这个问题。我会说我做了什么,但是更聪明的人可能会插进来解释更多的原因,因为我不知道为什么它会起作用。

解决方案:

在我替换的UpdateProductReqBody记录

import org.springframework.validation.annotation.Validated

public record UpdateFoodReqBody(
    String dietaryRestrictions,
    @Validated @NotNull UpdateProductReqBody product
){}

import jakarta.validation.Valid

public record UpdateFoodReqBody(
    String dietaryRestrictions,
    @Valid @NotNull UpdateProductReqBody product
){}

它工作了,但我不知道为什么。@Validated不就是JSR-303的jakvalidation.validation的Spring实现吗?

相关问题