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

Android Espresso测试如何无需添加代码分支Mock Activity依赖的类

可行实现方案

你完全不需要在生产代码里加任何分支逻辑,以下是3种成熟的落地方案:


方案1:依赖注入框架(最适合大型项目,长期可维护)

这是大型App做测试隔离的标准方案,不需要修改任何生产代码的业务逻辑,只需要补全依赖注入声明即可:

  • 给需要mock的类加注入注解,比如用Hilt的话给MainActivity2CustomClass加@Inject构造函数
  • Activity里不要直接new实例,改为字段注入:
@AndroidEntryPoint
public class MainActivity2 extends AppCompatActivity {
    @Inject
    MainActivity2CustomClass mainActivity2CustomClass;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        mainActivity2CustomClass.foo();
    }
}
  • 测试侧直接用Hilt的测试替换规则,全局或者单测试用例替换该类的实现为mock:
@HiltAndroidTest
public class MainActivity2Test {
    @Mock
    MainActivity2CustomClass mockCustomClass;

    @BindValue
    MainActivity2CustomClass bindMock = mockCustomClass;

    @Rule
    public HiltAndroidRule hiltRule = new HiltAndroidRule(this);

    @Test
    public void testFoo() {
        // 先打桩mock的行为
        doNothing().when(mockCustomClass).foo();
        // 启动Activity,拿到的就是mock实例
        ActivityScenario.launch(MainActivity2.class);
    }
}

优势:全局可复用,所有需要mock的类都可以通过同一套规则替换,无生产代码侵入,性能无损耗


方案2:构造方法Mock(零生产代码修改,适合不想改现有架构的场景)

用Mockito 3.5+自带的构造方法Mock能力,直接拦截Activity中new类的逻辑,返回mock实例,完全不需要动生产代码:

@Test
public void testMockConstructor() {
    // mock所有MainActivity2CustomClass的构造调用,返回mock实例
    try (MockedConstruction<MainActivity2CustomClass> mocked = mockConstruction(MainActivity2CustomClass.class, (mock, context) -> {
        // 自定义mock的行为
        doNothing().when(mock).foo();
    })) {
        ActivityScenario.launch(MainActivity2.class);
        // 验证构造方法被调用,foo方法被调用
        MainActivity2CustomClass constructedInstance = mocked.constructed().get(0);
        verify(constructedInstance).foo();
    }
}

优势:零生产代码修改,适合临时给老项目加测试的场景


方案3:测试变体SourceSet替换(零侵入,成本最低)

如果你的类是public可替换的,直接在androidTest的sourceSet下创建完全相同包名类名的类,构建时测试变体优先使用test下的类:

  • 在src/androidTest/java/[你的类对应包路径]/路径下创建和生产代码完全同包名同类名的MainActivity2CustomClass
  • 测试构建时会优先用androidTest下的这个类替换生产的类,完全不需要改任何生产代码
    优势:实现成本最低,不需要引入额外框架,适合少量类替换的场景

所有方案都不需要在生产代码中加任何测试相关的分支逻辑,完全满足大型项目的可维护性要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 10:06:02