【问题标题】:Disable Dagger injection in tests在测试中禁用 Dagger 注入
【发布时间】:2023-03-04 11:30:01
【问题描述】:

我有以下使用 Dagger 注入其字段的 LoginFragment:

class LoginFragment : DaggerFragment() {

    @Inject
    lateinit var viewModelFactory: ViewModelProvider.Factory

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)

        viewModel = ViewModelProviders.of(this, viewModelFactory)
                .get(LoginViewModel::class.java)
    }

根据 Google 的文档,我还有一个模拟 LoginViewModel 的相应测试:“您可以创建片段并为其提供模拟 ViewModel。”

@MediumTest
@RunWith(AndroidJUnit4::class)
class LoginFragmentTest {

    @Mock
    private lateinit var viewModel: LoginViewModel

    @Before
    fun setUp() {
        loginFragment = LoginFragment()

        loginFragment.viewModelFactory = createMockViewModelFactory(viewModel)

        activityRule.activity.setFragment(loginFragment)
    }
}

问题是,当调用fragment的onAttached方法时,Dagger用自己的对象覆盖了viewModelFactory,从而替换了我的mock。

如何防止 Dagger 覆盖我的模拟对象?

【问题讨论】:

    标签: android unit-testing mockito dagger-2


    【解决方案1】:

    在 Github 上的 android-architecture-components 示例中,Google 有一个有趣的解决方案。

    他们inject活动槽ActivityLifecycleCallbacks。对于插桩测试,他们使用 TestApp 不注册 ActivityLifecycleCallbacks 所以它什么都不注入。

    就像在您的示例中一样,ViewModel.Factory 是包私有的,因此在测试中您可以自己分配它。

    对于Fragments,可以使用FragmentManager.FragmentLifecycleCallbacks 类。而不是FragmentonActivityCreated 中注入自己,您的生产活动使用FragmentLifecycleCallbacks 注入Fragment。您可以创建一个不注入片段的测试活动,也可以自己创建一个模拟工厂。

    【讨论】:

    • 谢谢,听起来很有趣。我会试一试的。
    • 效果很好,我唯一担心的是注入发生在onActivityCreated()回调中,这可能为时已晚,因为建议在调用@之前立即在onCreate()中调用AndroidInjection.inject() 987654337@(在此处查看“何时注入”部分:google.github.io/dagger/android.html)。
    • @makovkastar 我建议使用onActivityCreated,因为那是您注入片段的地方。看看[onFragmentPreCreated](developer.android.com/reference/android/support/v4/app/…, android.support.v4.app.Fragment, android.os.Bundle))
    • 抱歉,我的评论有点混乱。我说的是注入活动本身的成员。对于片段,我使用了onFragmentPreAttached 回调,所以没问题。但是如果我们想注入一个活动的成员,onActivityCreated 可能为时已晚。
    • @makovkastar ActivityLifecycleCallbacks 的文档不清楚何时触发回调。但它用于 Google 官方示例。除非您遇到任何问题,否则它应该可以工作。
    猜你喜欢
    • 2019-01-02
    • 2021-10-16
    • 1970-01-01
    • 2017-05-20
    • 1970-01-01
    • 1970-01-01
    • 2017-01-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多