Search code examples
androidunit-testingmockitoandroid-testingrx-android

Android Unit testing run all class tests fail but every single method run successfully


please help me this when i run all the class test methods together the test fails in a method although this method when i run it alone it succeed

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();
}}

when i run all the tests together the first two methods pass but the last one fail (testWhenGetAllRealEstatesError_ProgressISHidden) but when i run it alone it pass.

and this is the presenter code

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());
    }));
}

}


Solution

  • i found the problem it is in RX Scheulers This error occurs because the default scheduler returned by AndroidSchedulers.mainThread() is an instance of LooperScheduler and relies on Android dependencies that are not available in JUnit tests.

    We can avoid this issue by initializing RxAndroidPlugins with a different Scheduler before the tests are run. You can do this inside of a @BeforeClass so the final class would be like this

    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();    }}