禁用测试中的Dagger注入

我有以下使用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)
    }
}

问题在于,当调用片段的onAttached方法时,Dagger用其自己的对象覆盖viewModelFactory,从而替换了我的模拟对象.

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

解决方法:

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

他们将inject的活动穿过了ActivityLifecycleCallbacks.对于已进行测试的测试,他们使用的是TestApp,它未注册ActivityLifecycleCallbacks,因此不会注入任何内容.

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

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

上一篇:java-我该如何模拟void方法,并使用Mockito使其保持不变?


下一篇:poj_2739 尺取法