MockMVC测试会员信息修改PUT接口时昵称未更新问题排查求助
首先看你的错误日志里的Resolved Exception: Type = org.springframework.http.converter.HttpMessageConversionException,这就是问题的核心:请求体无法正确转换为MemberUpdateDto,导致你的更新逻辑根本没执行起来。
为什么会出现这个问题?
你的MemberUpdateDto定义了一个带Optional<String>参数的构造器,但:
- 构造器的参数名是
updateNickname,而你测试代码里传的JSON字段是nickname,Jackson没法把这两个对应起来; - 即使参数名匹配,Jackson默认也没法直接把JSON里的普通字符串映射到构造器的
Optional<String>参数(除非你明确告诉它怎么做)。
结果就是,memberUpdateDto.getNickname()拿到的是Optional.empty(),Service里的ifPresent逻辑直接跳过,自然不会更新昵称。
怎么解决?
推荐两种简单的修复方案:
方案1:给构造器参数添加@JsonProperty注解
让Jackson明确知道构造器参数对应JSON里的哪个字段:
@Data public class MemberUpdateDto { private Optional<String> nickname; public MemberUpdateDto(@JsonProperty("nickname") Optional<String> nickname) { this.nickname = nickname; } }
方案2:去掉自定义构造器(更简洁推荐)
依赖@Data生成的无参构造器和setter,Spring Boot默认已经引入了jackson-datatype-jdk8模块,它会自动把JSON里的字符串转换成Optional<String>:
@Data public class MemberUpdateDto { private Optional<String> nickname; // 不需要自定义构造器,@Data会自动生成无参构造器和setter }
额外注意:测试事务回滚
你的日志里显示Rolled back transaction for test,这是Spring Boot测试默认的@Transactional行为——测试结束后会回滚所有数据库操作。不过当前你的问题核心是DTO转换失败,所以先修复上面的问题,更新逻辑执行后,在同一个事务里的assertThat是能看到修改结果的(回滚是在测试方法结束后才发生)。
验证
修改完DTO后重新运行测试,memberUpdateDto.getNickname()会正确拿到Optional.of("sdfachange"),Service里的更新逻辑会执行,你的断言就能匹配到修改后的昵称了。
内容的提问来源于stack exchange,提问作者zhao

