4

我的应用程序开发基于来自 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 模拟器运行我的测试。

我很感激你能给我的所有帮助。

4

0 回答 0