包含CompositeDisposable的测试演示者

时间:2018-09-05 10:08:56

标签: android unit-testing kotlin mockito rx-java2

我尝试为我的演示者类创建单元测试,该类使用RxJava CompositeDisposable,但始终提供空指针异常。

这是我的主持人班:

class LastMatchPresenter(val mView :  MatchContract.View,
                     val matchRepositoryImpl: MatchRepositoryImpl,
                     val scheduler: SchedulerProvider) : MatchContract.Presenter{

    val compositeDisposable = CompositeDisposable()

    override fun getFootballMatchData() {
        mView.showLoading()
        compositeDisposable.add(matchRepositoryImpl.getFootballMatch("4328")
                .observeOn(scheduler.ui())
                .subscribeOn(scheduler.io())
                .subscribe{
                    mView.displayFootballMatch(it.events)
                    mView.hideLoading()
                })
    }
}

这是测试类:

class LastMatchPresenterTest {

    @Mock
    lateinit var mView: MatchContract.View

    @Mock
    lateinit var matchRepositoryImpl: MatchRepositoryImpl

    lateinit var scheduler: SchedulerProvider

    lateinit var mPresenter: LastMatchPresenter

    @Before
    fun setUp() {
        MockitoAnnotations.initMocks(this)
        scheduler = TestSchedulerProvider()
        mPresenter = LastMatchPresenter(mView, matchRepositoryImpl, scheduler)
    }

    @Test
    fun getFootballMatchData() {
        mPresenter.getFootballMatchData()
        mView.showLoading()
    }
}

当我运行测试时,它给了我以下错误:

java.lang.NullPointerException
at com.rahmat.app.footballclub.feature.lastmatch.LastMatchPresenter.getFootballMatchData(LastMatchPresenter.kt:20)
at com.rahmat.app.footballclub.feature.lastmatch.LastMatchPresenterTest.getFootballMatchData(LastMatchPresenterTest.kt:43)

它指向的位置:

此行.observeOn(scheduler.ui())

3 个答案:

答案 0 :(得分:1)

我不知道这是否可以帮助您。

但是当我有一个Presenter和PresenterTest时,我允许您使用一些代码。

演示者:

...
private void loadRepos() {
        disposableManager.add(repoRepository.getTrendingRepos()
                .doOnSubscribe(__ -> viewModel.loadingUpdated().accept(true))
                .doOnEvent((d, t) -> viewModel.loadingUpdated().accept(false))
                .doOnSuccess(__ -> viewModel.reposUpdated().run())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(dataSource::setData, viewModel.onError()));
        }
...

我观察到mainThread中的更改,但是在测试中,我更改了调度程序以运行它。

然后在PresenterTest中添加它以运行测试。

PresenterTest:

public class TrendingReposPresenterTest {

    static {
        RxAndroidPlugins.setInitMainThreadSchedulerHandler(schedulerCallable -> Schedulers.trampoline());
    }

...

  private void initializePresenter() {
            presenter = new TrendingReposPresenter(viewModel, repoRepository,
                    screenNavigator,Mockito.mock(DisposableManager.class),dataSource);
        }

这是我的可处理经理班,负责处理可观察对象。

DisposableManager

public class DisposableManager {

    private final CompositeDisposable compositeDisposable = new CompositeDisposable();

    public void add(Disposable... disposables) {
        compositeDisposable.addAll(disposables);
    }

    public void dispose() {
        compositeDisposable.clear();
    }
}

希望这对您有所帮助。但是我不确定这是否是你的问题

答案 1 :(得分:0)

matchRepositoryImpl.getFootballMatch(“ 4328”)可能返回null。您模拟了matchRepositoryImpl,但没有模拟它的getFootballMatch方法。这是个快速的猜测。

顺便说一句,如果您使用Kotlin进行测试,我建议您尝试使用MockK

答案 2 :(得分:0)

您必须像这样模拟matchRepositoryImpl.getFootballMatch("4328")方法:

Mockito.`when`(matchRepositoryImpl.getFootballMatch("4328"))
        .thenReturn(Observable.just(OBJECT_YOU_WANT_TO_BE_RETURNED))

您可以将此模拟程序放在@Before块中,或进行特殊测试。