Android JUnit中Mock方法调用返回null的问题排查
问题分析与解决方案
你遇到的核心问题是Mock对象的方法默认行为导致getChartTypeJS()没有执行真实逻辑,具体原因和修复方案如下:
为什么你的测试会返回null?
你用@Mock创建的loadJsonData是一个完全Mock的代理对象——Mockito生成的Mock对象,所有未显式Mock的方法都会返回默认值(比如String类型返回null)。
虽然你Mock了getJsonData()让它返回预期的JSON字符串,但getChartTypeJS()作为Mock对象的方法,并不会执行你写的真实代码逻辑,只是直接返回默认的null,这就是问题所在。
修复方案:使用Spy或调用真实方法的Mock配置
要让getChartTypeJS()执行真实逻辑,同时只MockgetJsonData(),你有两种常用方式:
方式1:使用@Spy保留真实方法实现
Spy对象会保留类的真实方法逻辑,只有你显式Mock的方法才会被替换:
@RunWith(MockitoJUnitRunner.class) public class LoadJsonData_Test { // 如果LoadJsonData需要Context构造,先Mock Context @Mock private Context mContext; // 创建Spy对象,保留真实方法逻辑 @Spy private LoadJsonData loadJsonData = new LoadJsonData(mContext); @Test public void getChartTypeJS_test() { String jsonStr = ""; try { InputStream is = this.getClass().getClassLoader().getResourceAsStream("chartInfo.json"); int size = is.available(); byte[] buffer = new byte[size]; if (is.read(buffer) > 0) jsonStr = new String(buffer, "UTF-8"); is.close(); } catch (IOException ex) { ex.printStackTrace(); } // Mock getJsonData方法,替换它的返回值 doReturn(jsonStr).when(loadJsonData).getJsonData(); // 此时getChartTypeJS会执行真实逻辑,调用被Mock的getJsonData assertEquals(loadJsonData.getChartTypeJS(), "javascript:setChartSeriesType(%d);"); } }
方式2:用CALLS_REAL_METHODS配置Mock对象
也可以直接在Mock时指定,让未被Mock的方法执行真实逻辑:
@RunWith(MockitoJUnitRunner.class) public class LoadJsonData_Test { // 配置Mock对象调用真实方法,除非被显式Mock @Mock(answer = Answers.CALLS_REAL_METHODS) private LoadJsonData loadJsonData; @Test public void getChartTypeJS_test() { String jsonStr = ""; try { InputStream is = this.getClass().getClassLoader().getResourceAsStream("chartInfo.json"); int size = is.available(); byte[] buffer = new byte[size]; if (is.read(buffer) > 0) jsonStr = new String(buffer, "UTF-8"); is.close(); } catch (IOException ex) { ex.printStackTrace(); } when(loadJsonData.getJsonData()).thenReturn(jsonStr); assertEquals(loadJsonData.getChartTypeJS(), "javascript:setChartSeriesType(%d);"); } }
额外注意事项
- 如果你的
LoadJsonData构造方法依赖Context,一定要Mock一个Context对象传入,否则会抛出初始化异常(即使你已经Mock了getJsonData())。 - 使用
doReturn()替代when()来MockSpy对象的方法,能避免触发真实方法的执行(某些场景下when()会先调用一次真实方法)。
内容的提问来源于stack exchange,提问作者Sindhu
相关产品推荐
相关产品推荐

