为什么在使用RobolectricTestRunner时,模拟对象函数抛出空值而不是模拟数据?

时间:2019-04-10 21:34:19

标签: android kotlin mockito robolectric

我之前有这个测试类与MockitoJUnitRunner一起运行,然后我添加了RoboLectric,现在我使用RobolectricTestRunner

因此,它尝试的第一件事是运行我的旧测试,但是仅更改运行程序,现在测试总是失败。我真的不太了解这里发生了什么,我只是想在不停止使用RobolectricTestRunner的情况下使用Mockito进行旧测试。

更改为RoboLectric(成功通过测试)之前的我的代码

@RunWith(MockitoJUnitRunner::class)
class LauncherViewModelTest {

    companion object {
        @ClassRule
        @JvmField
        val schedulers = RxImmediateeSchedulerRule()
    }

    @Rule
    @JvmField
    val rule = InstantTaskExecutorRule()

    @Mock
    private lateinit var mockContext: MyApplication

    @Mock
    private lateinit var mockedDatabase: MyDatabase

    @Mock
    private lateinit var session: Session

    // 
    @Mock
    lateinit var mockedDatabaseRxWrapper: DatabaseRxWrapper

    /** Evaluated class **/

    @InjectMocks
    lateinit var launcherViewModel: LauncherViewModel

    @Test
    fun checkIfHasSessionSuccess() {

        val sessionFlowable: Flowable<Session> = Flowable.fromCallable { session }

        FieldSetter.setField(launcherViewModel,
                launcherViewModel.javaClass.getDeclaredField("databaseRxWrapper"), mockedDatabaseRxWrapper)

        doReturn(sessionFlowable).`when`(mockedDatabaseRxWrapper).getSession()

        launcherViewModel.checkIfHasSession()

        //$hasSession is a mutable live data
        Assert.assertEquals(true, launcherViewModel.hasSession.value)
    }
}

更改为RoboLectric之后的代码:(即使我使用Mockito.doReturn()。when()),DatabaseRxWrapper.getSession()始终返回null

@RunWith(RobolectricTestRunner::class)
class LauncherViewModelTest {

    companion object {
        @ClassRule
        @JvmField
        val schedulers = RxImmediateeSchedulerRule()
    }

    @Rule
    @JvmField
    val rule = InstantTaskExecutorRule()

    @get:Rule
    val mockitoRule = MockitoJUnit.rule()

    @Mock
    private lateinit var mockContext: MyApplication

    @Mock
    private lateinit var mockedDatabase: MyDatabase

    @Mock
    private lateinit var session: Session

    // 
    @Mock
    lateinit var mockedDatabaseRxWrapper: DatabaseRxWrapper

    /** Evaluated class **/

    @InjectMocks
    lateinit var launcherViewModel: LauncherViewModel

    @Test
    fun checkIfHasSessionSuccess() {

        val sessionFlowable: Flowable<Session> = Flowable.fromCallable { session }

        FieldSetter.setField(launcherViewModel,
                launcherViewModel.javaClass.getDeclaredField("databaseRxWrapper"), mockedDatabaseRxWrapper)

        doReturn(sessionFlowable).`when`(mockedDatabaseRxWrapper).getSession()

        launcherViewModel.checkIfHasSession()

        //$hasSession is a mutable live data
        Assert.assertEquals(true, launcherViewModel.hasSession.value)
    }
}

被测类

class LauncherViewModel(application: Application) : AndroidViewModel(application) {

        @Inject
        lateinit var databaseRxWrapper: DatabaseRxWrapper

        val hasSession: MutableLiveData<Boolean> = MutableLiveData()

        val application by lazy { getApplication<MyApplication>() }

        init {
            application.getAppComponent()?.inject(this)
        }

        fun saveLocation(location: Location) = sharedPreferenceManager.saveLocation(location)

        fun checkIfHasSession() {
            databaseRxWrapper.getSession()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe({
                    hasSession.postValue(true)
                }, {
                    hasSession.postValue(false)
                })
        }
    }

1 个答案:

答案 0 :(得分:0)

我发现,如果您使用Robolectric运行,则不需要重写RX配置的规则

因此,该代码在删除该类规则后有效:

companion object {
        @ClassRule
        @JvmField
        val schedulers = RxImmediateeSchedulerRule()
    }