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

JUnit测试报错:无法将VALUE_STRING/VALUE_TRUE反序列化为ArrayList

解决Jackson反序列化List时的类型不匹配问题

看起来你遇到的核心问题是Mock返回的JSON字符串格式和被测方法期望的类型完全不匹配,咱们一步步拆解解决:

报错原因分析

  1. 第一个错误Unrecognized token 'test':你返回的"test"根本不是合法的JSON格式,Jackson完全无法解析它。
  2. 第二个错误Cannot deserialize instance of java.util.ArrayList out of VALUE_TRUE token:你返回的"true"是合法JSON,但它是单个布尔值,而被测方法里要把它反序列化成List<Measurement>/List<Meal>/List<Training>——Jackson没法把单个布尔值转换成列表,自然会抛出类型不匹配的异常。

解决方案:返回合法的JSON数组格式

被测方法里的objectMapper.readValue(..., TypeReference<List<X>>())要求传入的JSON必须是JSON数组(用[]包裹的格式),所以你需要给每个getJSON调用返回对应类型的数组JSON:

方案1:返回空数组(适合测试空列表场景)

@Before public void setUp() throws Exception { 
    activitiesService = new ActivitiesService(databaseControllerMock); 
    when(databaseControllerMock.get(anyString(), any())).thenReturn(item); 
    // 给三个字段都返回空数组JSON
    when(item.getJSON("measurements")).thenReturn("[]");
    when(item.getJSON("meals")).thenReturn("[]");
    when(item.getJSON("trainings")).thenReturn("[]");
}

方案2:返回带测试数据的JSON数组(适合测试非空列表场景)

如果需要测试有数据的情况,可以手动构造符合实体类字段的JSON数组,比如假设Measurement有id和value字段:

@Before public void setUp() throws Exception { 
    activitiesService = new ActivitiesService(databaseControllerMock); 
    when(databaseControllerMock.get(anyString(), any())).thenReturn(item); 
    // 带示例数据的数组JSON
    when(item.getJSON("measurements")).thenReturn("[{\"id\":1, \"value\":120.5}]");
    when(item.getJSON("meals")).thenReturn("[{\"name\":\"Lunch\", \"calories\":500}]");
    when(item.getJSON("trainings")).thenReturn("[{\"name\":\"Swimming\", \"minutes\":45}]");
}

方案3:用ObjectMapper自动生成JSON(更灵活,避免手动写JSON出错)

如果实体类字段较多,手动写JSON容易出错,可以先创建测试用的实体列表,再用ObjectMapper转成JSON字符串:

@Before public void setUp() throws Exception { 
    activitiesService = new ActivitiesService(databaseControllerMock); 
    when(databaseControllerMock.get(anyString(), any())).thenReturn(item); 

    ObjectMapper mapper = new ObjectMapper();
    // 构造测试用的Measurement列表
    List<Measurement> mockMeasurements = Arrays.asList(new Measurement(1, 120.5));
    String measurementsJson = mapper.writeValueAsString(mockMeasurements);
    when(item.getJSON("measurements")).thenReturn(measurementsJson);

    // 同理处理meals和trainings
    List<Meal> mockMeals = Arrays.asList(new Meal("Lunch", 500));
    when(item.getJSON("meals")).thenReturn(mapper.writeValueAsString(mockMeals));

    List<Training> mockTrainings = Arrays.asList(new Training("Swimming", 45));
    when(item.getJSON("trainings")).thenReturn(mapper.writeValueAsString(mockTrainings));
}

这样Mock返回的JSON就能被Jackson正确反序列化成对应的List对象,解决你的报错问题啦。

内容的提问来源于stack exchange,提问作者D.Zet

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:47:20