Spring Boot REST API返回Course列表测试用例报错排查
问题排查:TestRestTemplate调用课程列表API失败及断言不符问题
核心问题点
- Postman调用课程列表API可正常返回数据,但JUnit测试用
TestRestTemplate调用时抛出org.springframework.web.client.RestClientException: Error while extracting response for type [java.util.List[com.socgen.jpa.hibernate.learnjpa.entity.Course]] and content type [application/json] data.sql仅插入1条课程数据,但测试用例断言返回列表长度为2,其余测试用例均正常通过
排查步骤
1. 定位响应解析失败的根源
1.1 先打印原始响应,确认JSON格式
在测试用例中先获取原始响应字符串,排查返回的JSON是否符合预期:
String rawResponse = testRestTemplate.getForObject("/courses", String.class); System.out.println("API返回原始JSON:" + rawResponse);
常见解析失败原因:
- JSON字段与
Course实体类属性不匹配(比如实体类用了@JsonProperty但字段名未对齐) Course类缺少公共无参构造函数(Spring JSON解析器依赖无参构造实例化对象)- 响应JSON是嵌套结构(比如外层有
data包裹,但测试直接解析为List<Course>)
1.2 检查Course实体类配置
确保实体类满足JSON解析要求:
- 必须有公共无参构造:
public Course() { // Jackson解析必须依赖无参构造 }
- 字段的getter/setter齐全,或使用
@Data(Lombok)注解自动生成 - 日期、特殊类型字段需配置正确的序列化/反序列化规则(比如
@DateTimeFormat)
2. 解决断言列表长度为2的问题
2.1 确认数据库实际数据量
注入JdbcTemplate打印测试时的数据库数据量,排查data.sql执行是否符合预期:
@Autowired private JdbcTemplate jdbcTemplate; @Test void testCourseList() { int dbCount = jdbcTemplate.queryForObject("SELECT COUNT(*) FROM course", Integer.class); System.out.println("数据库中课程数量:" + dbCount); // 后续TestRestTemplate调用逻辑 }
2.2 排查测试上下文数据污染
- 如果测试类加了
@Transactional,测试结束会回滚,但多测试用例共享上下文时可能出现数据累加 - 给测试类添加
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD),确保每个测试方法执行后重置上下文,避免数据残留
3. 修正TestRestTemplate的调用方式
直接用getForObject解析泛型List<Course>容易出现类型推断错误,改用exchange方法明确指定参数化类型:
ResponseEntity<List<Course>> response = testRestTemplate.exchange( "/courses", HttpMethod.GET, null, new ParameterizedTypeReference<List<Course>>() {} ); List<Course> courses = response.getBody();
4. 检查依赖冲突
确保JSON解析相关依赖版本一致:
- 避免同时引入Gson和Jackson,导致解析器混乱
- 确认
spring-boot-starter-web依赖已包含正确的Jackson模块,无需手动引入冲突版本:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
内容的提问来源于stack exchange,提问作者Destravna
相关产品推荐
相关产品推荐

