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

Android MVP:MainActivity单元测试——验证onCreate调用Presenter的A()方法

验证MainActivity onCreate中是否调用Presenter的A()方法

要实现这个单元测试,我们可以借助Mockito框架来模拟Presenter对象,并验证方法调用情况。下面分两种情况来讲解:

一、针对现有代码的测试方案(无需修改原Activity代码)

你的MainActivity在onCreate里直接new了MainPresenter,所以测试时需要通过反射替换掉真实的Presenter实例,用Mock对象来追踪方法调用。

1. 添加必要依赖

首先在app/build.gradle的dependencies块中引入测试依赖:

// JUnit 核心依赖
testImplementation 'junit:junit:4.13.2'
// Mockito 核心库
testImplementation 'org.mockito:mockito-core:4.5.1'
// 如果是Android Instrumented测试(可选)
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'org.mockito:mockito-android:4.5.1'

2. 编写单元测试类

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import android.os.Bundle;
import static org.mockito.Mockito.verify;

@RunWith(MockitoJUnitRunner.class)
public class MainActivityTest {

    // 模拟MainPresenter对象
    @Mock
    private MainPresenter mockPresenter;

    private MainActivity activityUnderTest;

    @Before
    public void setUp() {
        activityUnderTest = new MainActivity();
        
        // 通过反射替换Activity中的presenter字段为Mock对象
        try {
            java.lang.reflect.Field presenterField = MainActivity.class.getDeclaredField("presenter");
            presenterField.setAccessible(true);
            presenterField.set(activityUnderTest, mockPresenter);
        } catch (NoSuchFieldException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    @Test
    public void onCreate_InvokesPresenterMethodA() {
        // 触发Activity的onCreate生命周期
        activityUnderTest.onCreate(new Bundle());
        
        // 验证MockPresenter的A()方法是否被调用了一次
        verify(mockPresenter).A();
    }
}

二、优化代码让测试更简洁(推荐)

上面的反射方式虽然能工作,但不够优雅。我们可以稍微改造MainActivity,通过构造方法注入Presenter,这样测试时就不需要反射了:

1. 改造MainActivity

public class MainActivity implements MainContract.View { 
    private MainPresenter presenter; 

    // 供测试使用的构造方法,传入Presenter实例
    public MainActivity(MainPresenter presenter) {
        this.presenter = presenter;
    }

    // 保留默认构造方法,供Android系统调用
    public MainActivity() {}

    @Override 
    protected void onCreate(final Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState);
        // 如果Presenter未初始化(通过默认构造方法创建Activity时),再实例化
        if (presenter == null) {
            presenter = new MainPresenter(this); 
        }
        presenter.A(); 
    } 
}

2. 简化后的测试类

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import android.os.Bundle;
import static org.mockito.Mockito.verify;

@RunWith(MockitoJUnitRunner.class)
public class MainActivityTest {

    @Mock
    private MainPresenter mockPresenter;

    private MainActivity activityUnderTest;

    @Before
    public void setUp() {
        // 直接通过构造方法注入MockPresenter
        activityUnderTest = new MainActivity(mockPresenter);
    }

    @Test
    public void onCreate_ShouldCallPresenterMethodA() {
        activityUnderTest.onCreate(new Bundle());
        // 验证方法调用
        verify(mockPresenter).A();
    }
}

关键说明

  • @Mock:用于创建模拟对象,Mockito会替我们生成一个实现了MainPresenter的代理类,我们可以追踪它的所有方法调用。
  • verify(mockPresenter).A():断言A()方法被调用了一次,如果没调用或者调用次数不对,测试会失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:18:14