[英]Android Unit testing run all class tests fail but every single method run successfully
请帮助我,当我一起运行所有类测试方法时,测试在一个方法中失败,尽管当我单独运行此方法时它成功了
public class RealEstatesListPresenterTest {
RealEstatesListPresenter mRealEstatesListPresenter;
@Mock
private RealEstateListBusiness mRealEstateListBusiness;
@Mock
private RealEstatesListContract.View mRealEstatesView;
@BeforeClass
public static void setUpClass() {
RxAndroidPlugins.setInitMainThreadSchedulerHandler(__ -> Schedulers.trampoline());
}
@Before
public void setupTasksPresenter() {
MockitoAnnotations.initMocks(this);
mRealEstatesListPresenter = new RealEstatesListPresenter(mRealEstatesView);
mRealEstatesListPresenter.setmRealEstateListBusiness(mRealEstateListBusiness);
}
@Test
public void testWhenGetAllRealEstates_ProgressISDisplayed() {
when(mRealEstateListBusiness.getAllRealEstates()).thenReturn(Observable.create(sub -> {
sub.onNext(new ArrayList<>());
sub.onComplete();
}));
mRealEstatesListPresenter.getAllRealEstates();
verify(mRealEstatesView, times(1)).showLoading();
}
@Test
public void testWhenGetAllRealEstatesSuccess_ProgressISHidden() {
when(mRealEstateListBusiness.getAllRealEstates()).thenReturn(Observable.create(sub -> {
sub.onNext(new ArrayList<>());
sub.onComplete();
}));
mRealEstatesListPresenter.getAllRealEstates();
verify(mRealEstatesView, times(1)).hideLoading();
}
@Test
public void testWhenGetAllRealEstatesError_ProgressISHidden() {
when(mRealEstateListBusiness.getAllRealEstates()).thenReturn(Observable.create(sub -> {
sub.onError(new Throwable());
}));
mRealEstatesListPresenter.getAllRealEstates();
verify(mRealEstatesView, times(1)).hideLoading();
}
@AfterClass
public static void tearDownClass() {
RxAndroidPlugins.reset();
}}
当我一起运行所有测试时,前两种方法通过但最后一种失败(testWhenGetAllRealEstatesError_ProgressISHidden)但是当我单独运行它时它通过。
这是演示者代码
public class RealEstatesListPresenter implements RealEstatesListContract.Presenter {
private RealEstatesListContract.View mView;
private RealEstateListBusiness mRealEstateListBusiness;
private CompositeDisposable mSubscriptions;
@Inject
public RealEstatesListPresenter(RealEstatesListContract.View view) {
this.mView = view;
mSubscriptions = new CompositeDisposable();
}
@Inject
public void setmRealEstateListBusiness(RealEstateListBusiness mRealEstateListBusiness) {
this.mRealEstateListBusiness = mRealEstateListBusiness;
}
@Inject
public void setupListeners() {
mView.setPresenter(this);
}
@Override
public void unSubscribe() {
mSubscriptions.clear();
}
@Override
public void getAllRealEstates() {
mView.showLoading();
mSubscriptions.add(mRealEstateListBusiness.getAllRealEstates().observeOn(AndroidSchedulers.
mainThread()).subscribeOn(Schedulers.io()).subscribe((realEstatesItems) -> {
mView.hideLoading();
mView.showAllRealEstates(realEstatesItems);
}, throwable -> {
mView.hideLoading();
mView.showErrorMessage(throwable.getMessage());
}));
}
}
我发现问题出在 RX Scheulers 发生此错误的原因是 AndroidSchedulers.mainThread() 返回的默认调度程序是 LooperScheduler 的一个实例,并且依赖于 JUnit 测试中不可用的 Android 依赖项。
我们可以通过在运行测试之前使用不同的调度程序初始化 RxAndroidPlugins 来避免这个问题。 您可以在 @BeforeClass 内部执行此操作,因此最终类将是这样的
public class RealEstatesListPresenterTest {
private RealEstatesListPresenter mRealEstatesListPresenter;
@Mock
private RealEstateListBusiness mRealEstateListBusiness;
@Mock
private RealEstatesListContract.View mRealEstatesView;
@BeforeClass
public static void setUpClass() {
Scheduler immediate = new Scheduler() {
@Override
public Worker createWorker() {
return new ExecutorScheduler.ExecutorWorker(Runnable::run);
}
};
RxJavaPlugins.setInitIoSchedulerHandler(scheduler -> immediate);
RxJavaPlugins.setInitComputationSchedulerHandler(scheduler -> immediate);
RxJavaPlugins.setInitNewThreadSchedulerHandler(scheduler -> immediate);
RxJavaPlugins.setInitSingleSchedulerHandler(scheduler -> immediate);
RxAndroidPlugins.setInitMainThreadSchedulerHandler(scheduler -> immediate); }
@Before
public void setupTasksPresenter() {
MockitoAnnotations.initMocks(this);
mRealEstatesListPresenter = new RealEstatesListPresenter(mRealEstatesView);
mRealEstatesListPresenter.setmRealEstateListBusiness(mRealEstateListBusiness);
}
@Test
public void testWhenGetAllRealEstates_ProgressISDisplayed() {
when(mRealEstateListBusiness.getAllRealEstates()).thenReturn(Observable.create(sub -> {
sub.onNext(new ArrayList<>());
sub.onComplete();
}));
mRealEstatesListPresenter.getAllRealEstates();
verify(mRealEstatesView, times(1)).showLoading();
}
@Test
public void testWhenGetAllRealEstatesSuccess_ProgressISHidden() {
when(mRealEstateListBusiness.getAllRealEstates()).thenReturn(Observable.create(sub -> {
sub.onNext(new ArrayList<>());
sub.onComplete();
}));
mRealEstatesListPresenter.getAllRealEstates();
verify(mRealEstatesView, times(1)).hideLoading();
}
@Test
public void testWhenGetAllRealEstatesError_ProgressISHidden() {
when(mRealEstateListBusiness.getAllRealEstates()).thenReturn(Observable.create(sub -> {
sub.onError(new Throwable());
}));
mRealEstatesListPresenter.getAllRealEstates();
verify(mRealEstatesView, times(1)).hideLoading();
}
@Test
public void testWhenGetAllRealEstatesError_ErrorMessageDisplayed() {
when(mRealEstateListBusiness.getAllRealEstates()).thenReturn(Observable.create(sub -> {
sub.onError(new Throwable(""));
}));
mRealEstatesListPresenter.getAllRealEstates();
verify(mRealEstatesView, times(1)).showErrorMessage("");
}
@After
public void teardown() {
Mockito.reset(mRealEstateListBusiness);
Mockito.reset(mRealEstatesView);
Mockito.validateMockitoUsage();
}
@AfterClass
public static void tearDownClass() {
RxJavaPlugins.reset();
RxAndroidPlugins.reset(); }}
我不确定代码本身但是如果每个测试运行成功,如果你只运行它,如果它与其他测试一起运行就会失败
然后,如果其他测试用例共享一些数据,在同一上下文中运行或访问相同的数据库、缓存、文件或任何存储库,则测试用例可能会损坏其他测试用例,每个测试用例应该成功运行,不依赖其他测试用例
当您使用 Mockito 时,似乎是上下文的问题,您应该在每个测试用例上重置模拟对象(即在 @Before 中) Mockito 提供了一个重置方法 Mockito.reset(mRealEstatesView);
问题是 mockito 在所有测试用例中计算该对象上的所有命中,所以你应该在每个测试用例之前重置它
您可以使用 Android Test Orchestrator。 正如你可以在这里阅读
使用 AndroidJUnitRunner 1.0 或更高版本时,您可以访问一个名为 Android Test Orchestrator 的工具,该工具允许您在自己的 Instrumentation 调用中运行应用程序的每个测试。
要将其添加到您的项目中:
androidTestUtil "androidx.test:orchestrator:1.2.0"
testOptions { execution 'ANDROIDX_TEST_ORCHESTRATOR' }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.