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
相关产品推荐
相关产品推荐

