You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring REST分页结果控制器测试报错问题求助

解决方案:MockMvc测试Page接口JSON解析错误问题

问题根源

你遇到的IllegalStateException: org.json.JSONException: Unparsable JSON string错误,本质是org.json库无法解析Spring Data Page类型序列化后的复杂JSON结构(Page包含content、pageable、sort等嵌套对象),而改用List时结构简单,所以解析正常。要验证分页信息,需换用Spring原生的Jackson工具或JsonPath来处理。


具体解决步骤

1. 确保MockMvc配置正确的Jackson消息转换器

Spring Data的Page类型需要PageJacksonModule支持序列化/反序列化,测试时要确保MockMvc使用配置了该模块的ObjectMapper:

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.data.web.PageJacksonModule;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;

@Autowired
private YourUserController userController;
@Autowired
private ObjectMapper objectMapper;

@BeforeEach
void setUp() {
    // 注册Page序列化模块
    objectMapper.registerModule(new PageJacksonModule());
    // 配置MockMvc使用Jackson消息转换器
    mockMvc = MockMvcBuilders.standaloneSetup(userController)
            .setMessageConverters(new MappingJackson2HttpMessageConverter(objectMapper))
            .build();
}

如果使用@WebMvcTest注解,Spring会自动配置兼容的ObjectMapper,只需确保依赖中包含spring-data-commons(PageJacksonModule在该包内)。

2. 用JsonPath直接验证分页信息

无需手动解析JSON字符串,直接用MockMvc的jsonPath断言分页相关字段,简洁高效:

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

@Test
void testUserPagination() throws Exception {
    mockMvc.perform(get("/users")
            .param("page", "0")
            .param("size", "10")
            .param("sort", "id,asc"))
            // 验证响应状态
            .andExpect(status().isOk())
            // 验证内容数量
            .andExpect(jsonPath("$.content.length()").value(10))
            // 验证总元素数
            .andExpect(jsonPath("$.totalElements").value(100))
            // 验证每页大小
            .andExpect(jsonPath("$.pageable.pageSize").value(10))
            // 验证排序状态和字段
            .andExpect(jsonPath("$.sort.sorted").value(true))
            .andExpect(jsonPath("$.sort.sortBy[0].property").value("id"))
            .andExpect(jsonPath("$.sort.sortBy[0].direction").value("ASC"));
}

3. 用Jackson将响应转成Page对象断言

如果需要更复杂的验证(比如检查具体User对象内容),可以将响应JSON转成Page<User>:

import org.springframework.test.web.servlet.MvcResult;
import com.fasterxml.jackson.core.type.TypeReference;

@Test
void testUserPageContent() throws Exception {
    MvcResult result = mockMvc.perform(get("/users")
            .param("page", "0")
            .param("size", "10"))
            .andExpect(status().isOk())
            .andReturn();

    // 将响应转成Page<User>
    Page<User> userPage = objectMapper.readValue(
            result.getResponse().getContentAsString(),
            new TypeReference<Page<User>>() {}
    );

    // 断言分页属性
    assertEquals(10, userPage.getSize());
    assertEquals(100, userPage.getTotalElements());
    assertEquals("id", userPage.getSort().stream().findFirst().get().getProperty());
    // 断言具体用户内容
    assertEquals("testUser1", userPage.getContent().get(0).getUsername());
}

4. 检查依赖兼容性

确保spring-data-commons和jackson-databind版本与Spring 3.4.1兼容,Java 21建议使用Jackson 2.17+版本:

<!-- Maven依赖示例 -->
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-commons</artifactId>
    <version>3.4.1</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.17.2</version>
</dependency>

内容的提问来源于stack exchange,提问作者CoderJammer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 07:53:27