碎片测试中的匕首注入问题

时间:2020-04-20 20:46:08

标签: android android-fragments kotlin junit4 androidx

我将我的应用开发基于android / architecture-components-samples包含测试的GithubBrowserSample。我已经完成了本地单元测试,但是使用UI测试时,我遇到了一些麻烦。

当我尝试测试任何片段时,我总是得到

java.lang.RuntimeException: kotlin.UninitializedPropertyAccessException: lateinit property viewModelFactory has not been initialized

这是我的片段测试

@RunWith(AndroidJUnit4::class)
class AccountListFragmentTest {

    @Rule
    @JvmField
    val executorRule = TaskExecutorWithIdlingResourceRule()

    @Rule
    @JvmField
    val countingAppExecutors = CountingAppExecutorsRule()

    @Rule
    @JvmField
    val dataBindingIdlingResourceRule = DataBindingIdlingResourceRule()

    private val navController = mock<NavController>()
    private val accountsLiveData = MutableLiveData<Resource<Accounts>>()
    private val triggerLiveData = MutableLiveData<Boolean>()
    private lateinit var viewModel: AccountListViewModel

    @Before
    fun init() {
        viewModel = mock(AccountListViewModel::class.java)

        `when`(viewModel.trigger).thenReturn(triggerLiveData)
        `when`(viewModel.accounts).thenReturn(accountsLiveData)
        doNothing().`when`(viewModel).setTrigger(true)

        val scenario = launchFragmentInContainer {
            AccountListFragment().apply {
                appExecutors = countingAppExecutors.appExecutors
                viewModelFactory = ViewModelUtil.createFor(viewModel)
            }
        }

        dataBindingIdlingResourceRule.monitorFragment(scenario)

        scenario.onFragment { fragment ->
            Navigation.setViewNavController(fragment.requireView(), navController)
            fragment.disableProgressBarAnimations()
        }
    }

    ...

}

在我的片段中,我像这样注入那些依赖关系

class AccountListFragment: Fragment(), Injectable {
    @Inject
    lateinit var viewModelFactory: ViewModelProvider.Factory
    @Inject
    lateinit var appExecutors: AppExecutors

    ...

所以我认为这与依赖注入有关。 在GithubBrowserSample中,他们提到您需要创建一个TestApp和一个CustomTestRunner以避免Dagger依赖注入,我已经完成了并将其添加到build.gradle

class TestApp : Application()

class CustomTestRunner : AndroidJUnitRunner() {
    override fun newApplication(cl: ClassLoader, className: String, context: Context): Application {
        return super.newApplication(cl, TestApp::class.java.name, context)
    }
}

//build.gradle
defaultConfig {
    ...
    testInstrumentationRunner "com.example.app.util.CustomTestRunner"
}

我的viewModel已经有@OpenForTesting注释,我正在使用其他viewModelFactory提供我的viewModel,所以我不知道我还需要做什么才能使其正常工作。

我正在使用Android Pixel 2 Api 29模拟器运行测试。

感谢您能给我的所有帮助。

0 个答案:

没有答案