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

Java单元测试中如何正确mock Arrays.asList相关方法调用?

问题解决:Mockito打桩Arrays.asList(Locale.getISOCountries()).contains()报错

错误原因

  • when()方法仅支持对Mockito生成的Mock对象的方法调用进行打桩,Arrays.asList(Locale.getISOCountries())返回的是JDK原生的ArrayList实例,不是Mock对象,调用其contains()方法时会直接执行真实逻辑,Mockito无法捕获该调用作为打桩匹配条件,导致返回值类型匹配混乱,触发WrongTypeOfReturnValue异常。
  • Locale.getISOCountries()是静态方法,@Mock Locale locale是对Locale实例对象的Mock,和静态方法无关,所以不会生效。
  • doReturn(true).when(Arrays.asList(Locale.getISOCountries()).contains(countryCode))写法不符合Mockito语法规范:doReturn.when()的参数要求传入Mock对象本身,而非方法调用结果。

解决方案

方案1:直接使用真实合法的国家码(最推荐)

JDK返回的ISO国家码列表是固定的,直接传入真实存在的国家码(如CN、US),contains()方法本身就会返回true,无需额外打桩:

// 示例:直接使用合法国家码测试,无需打桩
String testCountryCode = "CN";
// 执行业务逻辑即可

方案2:封装逻辑后Mock自定义方法

如果需要支持自定义国家列表,将国家码获取逻辑抽为独立的工具类方法,再对自定义方法打桩:

  1. 封装工具类:
public class CountryHelper {
    public List<String> getAllISOCountries() {
        return Arrays.asList(Locale.getISOCountries());
    }
}
  1. 单元测试中打桩:
@Mock
private CountryHelper countryHelper;

@Test
void testCountryValid() {
    String testCode = "TEST";
    when(countryHelper.getAllISOCountries()).thenReturn(List.of(testCode));
    // 后续执行业务逻辑即可
}

方案3:Mock静态方法(不推荐)

如果不想修改原有业务代码,可以引入mockito-inline依赖,直接MockLocale的静态方法:

try (MockedStatic<Locale> mockedLocale = Mockito.mockStatic(Locale.class)) {
    mockedLocale.when(Locale::getISOCountries).thenReturn(new String[]{"TEST"});
    // 执行业务逻辑
}

该方案会降低测试执行速度,且容易引发上下文污染问题,非必要不建议使用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 14:45:03