SpringBoot MVC测试密码不匹配场景预期400实际返回200问题咨询
问题解答
1. 你的结论是正确的
核心原因出在@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)注解上:这个注解的作用是限制字段仅允许JSON反序列化(即接口接收JSON数据时赋值给Java字段),Java对象序列化为JSON时会直接忽略该字段。
你测试时用objectMapper.writeValueAsString(newUser)把构造的User对象转为请求JSON,password和passwordConfirmation两个字段都标记了WRITE_ONLY,所以生成的请求JSON里根本没有这两个字段。接口侧反序列化时,两个字段取默认值空字符串,比对时自然相等,不会触发校验逻辑,相当于你传入服务层的User实体确实没有带你构造的密码值。
2. 存在这类数据
@Transient注解修饰的字段本身就不会被持久化到数据库,接口处理请求过程中生成的临时对象、未被存入响应体的字段值,都只会存在于JVM运行内存中,请求处理完成后就会被垃圾回收,不会落到数据库或者返回给前端。IntelliJ只是开发调试工具,本身不会存储你的业务数据,这类临时数据都是存在于应用启动的JVM进程内存里。
3. 按以下步骤修改即可触发预期报错
- 首先修改测试用例的请求构造逻辑:不要用User对象转JSON的方式生成请求体,直接手写JSON字符串传入,避免WRITE_ONLY字段被过滤,示例:
.content("{\"userName\":\"TestName\",\"email\":\"TestEmail@email.com\",\"password\":\"NOT_THE_SAME\",\"passwordConfirmation\":\"password123\",\"isAdmin\":true}")
- 如果你坚持要用对象转JSON的方式,可以修改测试用的ObjectMapper配置,关闭WRITE_ONLY字段的序列化限制,参考配置:
objectMapper = objectMapper.disable(MapperFeature.DEFAULT_VIEW_INCLUSION) .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
- 注意你当前Service层校验失败抛出的是
HttpStatus.NOT_FOUND(对应状态码404),而测试用例断言的是400,如果你预期返回400,需要把Service里的异常状态码改成HttpStatus.BAD_REQUEST。
内容的提问来源于stack exchange,提问作者Richard Smith-Uchotski
相关产品推荐
相关产品推荐

