【问题标题】:How to test DaggerFragment with FragmentScenario?如何使用 FragmentScenario 测试 DaggerFragment?
【发布时间】:2019-12-17 15:09:09
【问题描述】:

我有一个简单的Fragment,如下所示:

class SomeFragment : DaggerFragment() {
    ...
}

现在我想使用FragmentScenario 测试这个Fragment

class LoginFragmentTest {

    @Test
    fun test() {
        launchFragmentInContainer<SomeFragment>()
        onView(withId(R.id.someButton))
            .check(matches(isDisplayed()))
    }

}

但每次我尝试测试它总是:

java.lang.IllegalArgumentException:未找到 <...somefragment>

的注入器

如何正确运行测试?有人可以帮我吗?

【问题讨论】:

    标签: android dagger-2 android-fragmentscenario


    【解决方案1】:

    我找到了两种解决问题的方法:

    我认为第一种方法更简洁,建议使用它而不是后者,但我将对它们进行描述,以便您做出自己的选择。


    使用typealias构建风味

    1. 创建两种产品风味,mockprod

    app/build.gradle

    android {
        ...
        productFlavors {
            prod
            mock {
                applicationIdSuffix '.mock'
            }
        }
    }
    
    1. 然后根据口味设置typealias,我们称之为BaseFragment

    prod风味, app/src/prod/com.example.mypackage/BaseFragment.kt

    typealias BaseFragment = DaggerFragment
    

    mock 风味,app/src/mock/com.example.mypackage/BaseFragment.kt

    typealias BaseFragment = Fragment
    
    1. 最后在您的片段中使用 BaseFragment 别名:
    class SomeFragment : BaseFragment() {
       ...
    }
    
    1. 要使用FragmentScenario 测试代码,从prod* 构建变体切换到mock*,并设置所有应该在测试类中某处注入的依赖项(例如,使用模拟)

    拥有DaggerFragment并测试片段的变体

    1. 创建您自己的DaggerFragment(基于实际的dagger.android.support.DaggerFragment 实现):
    abstract class DaggerFragment() : Fragment(), HasAndroidInjector {
    
        @Inject
        lateinit var androidInjector: DispatchingAndroidInjector<Object>
    
        override fun onAttach(context: Context) {
            injectMembers()
            super.onAttach(context)
    
        override fun androidInjector(): AndroidInjector<Object> = androidInjector
    
        protected open fun injectMembers() = AndroidSupportInjection.inject(this)
    }
    
    1. 扩展您的DaggerFragment 实现并设置片段open
    open class SomeFragment : DaggerFragment() {
        ...
    }
    
    1. 为测试目的创建片段的另一个实现并覆盖injectMembers 方法:
    class TestSomeFragment : SomeFragment() {
    
        override injectMembers() {
            /* you can manually inject dependencies and mocks here */
        }
    }
    
    1. 在您的测试中使用TestSomeFragment

    【讨论】:

    • 我对这种方法的唯一问题是,现在,当您在其他变体上运行测试时,测试会失败。
    • @ArchieG.Quiñones 是的,不幸的是,这可能是一个缺点。但是,使用产品风格分离代码的测试和生产变体是recommended by Google developers,所以至少这是官方建议的不便。
    • 是的,我有点同意。我只是希望有比这更好的解决方案,但我认为这已经足够了,非常感谢:)
    猜你喜欢
    • 2019-05-06
    • 1970-01-01
    • 2020-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-01
    • 2012-05-26
    相关资源
    最近更新 更多