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

问题描述 投票:0回答:1

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

所以它尝试的第一件事是运行我的旧测试,但只是改变跑步者和测试现在总是失败。我真的不明白这里发生了什么,我只是想让我的旧测试工作与RobolectricTestRunner不停地使用Mockito

我的代码在更改为RoboLectric之前(TEST PASS FUCY)

@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后的我的代码:(DatabaseRxWrapper.getSession()返回总是为null,即使我使用Mockito.doReturn()。when())

@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)
                })
        }
    }
android kotlin mockito robolectric
1个回答
0
投票

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

因此删除此类规则后代码工作正常:

companion object {
        @ClassRule
        @JvmField
        val schedulers = RxImmediateeSchedulerRule()
    }
© www.soinside.com 2019 - 2024. All rights reserved.