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

如何用JUnit Mockito测试含JSONObject的函数?解决未Mock问题

解决Android测试中org.json.JSONObject not mocked的问题

这个错误是因为Android SDK中的org.json相关类在本地单元测试环境下只是存根(stub)实现,没有实际的功能逻辑,当你在测试中直接调用JSONObject的方法时,就会抛出这个异常。下面给你几种可行的解决办法,你可以根据自己的测试需求选择:

方法1:让测试返回系统类的默认值

在你的app模块的build.gradle文件中,添加测试配置,让未Mock的系统方法返回默认值(比如null、空字符串、0等):

android {
    // 其他已有的配置...
    testOptions {
        unitTests.returnDefaultValues = true
    }
}

这个方法最快捷,但要注意:如果你的测试逻辑依赖于JSON解析的真实结果,可能会因为默认值导致测试逻辑异常,适合简单场景的快速测试。

方法2:引入真实的JSON库替代系统存根

直接在测试依赖中引入独立的org.json库,这样测试环境会使用真实的JSON解析实现,而不是SDK的存根:

dependencies {
    // 其他依赖...
    testImplementation 'org.json:json:20230618'
}

这个方法不需要修改测试逻辑,直接就能让你的现有测试代码正常运行,适合需要验证真实JSON解析逻辑的场景。

方法3:Mock JSONObject调用(更符合单元测试隔离原则)

如果你的目标是测试getChartTypeJS的逻辑,而不是JSON解析本身,最好的方式是Mock掉JSONObject的相关调用,隔离对JSON库的依赖。步骤如下:

  1. 开启Mockito对final类的支持:
    在src/test/resources/mockito-extensions目录下创建一个名为org.mockito.plugins.MockMaker的文件,内容写:

    mock-maker-inline
    

    因为JSONObject是final类,Mockito默认不能Mock,这个配置可以让Mockito支持Mock final类。

  2. 重构待测试代码,抽离JSONObject创建逻辑:
    在LoadJsonData类中添加一个protected方法,把new JSONObject(jsonString)的逻辑抽出来,方便Mock:

    protected JSONObject createJSONObject(String json) throws JSONException {
        return new JSONObject(json);
    }
    

    然后修改getChartTypeJS方法,调用这个新方法:

    public String getChartTypeJS() {
        jsonString = getJsonData();
        try {
            JSONObject jsonObject = createJSONObject(jsonString);
            JSONObject javascriptEvent_JsonObject = jsonObject.getJSONObject("javascript_events");
            return javascriptEvent_JsonObject.getString("chartType");
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return "";
    }
    
  3. 修改测试代码,Mock相关对象:

    @RunWith(MockitoJUnitRunner.class)
    public class LoadJsonData_Test {
        @Spy
        private LoadJsonData loadJsonData;
    
        @Mock
        private JSONObject mockRootJson;
        @Mock
        private JSONObject mockJavascriptEventsJson;
    
        @Test
        public void getChartTypeJS_test() throws JSONException {
            // 模拟getJsonData返回的字符串(这里可以是任意结构,因为我们会Mock解析过程)
            String mockJsonStr = "{\"javascript_events\": {\"chartType\": \"test\"}}";
            doReturn(mockJsonStr).when(loadJsonData).getJsonData();
    
            // Mock JSONObject的创建和方法调用
            doReturn(mockRootJson).when(loadJsonData).createJSONObject(anyString());
            when(mockRootJson.getJSONObject("javascript_events")).thenReturn(mockJavascriptEventsJson);
            when(mockJavascriptEventsJson.getString("chartType")).thenReturn("javascript:setChartSeriesType(%d);");
    
            // 断言结果
            assertEquals(loadJsonData.getChartTypeJS(), "javascript:setChartSeriesType(%d);");
        }
    }
    

    这种方式完全隔离了真实的JSON解析逻辑,只测试getChartTypeJS方法的流程,更符合单元测试的核心思想。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:21:58