如何使用 FragmentScenario 测试 DaggerFragment?
How to test DaggerFragment with FragmentScenario?
我有一个简单的 Fragment
像这样:
class SomeFragment : DaggerFragment() {
...
}
现在我想使用 FragmentScenario
来测试这个 Fragment
class LoginFragmentTest {
@Test
fun test() {
launchFragmentInContainer<SomeFragment>()
onView(withId(R.id.someButton))
.check(matches(isDisplayed()))
}
}
但每次我尝试测试它总是:
java.lang.IllegalArgumentException: No injector was found for <...SomeFragment>
我怎样才能正确运行测试?有人可以帮我吗?
我找到了两种解决问题的方法:
- 使用单独的构建风格进行测试和
typealias
,
- creating your own
DaggerFragment
and special test variants of your fragments
我认为第一种方法更简洁,建议使用它而不是后者,但我将描述这两种方法,以便您做出自己的选择。
使用 typealias
构建风格
- 创建两种产品口味,
mock
和 prod
:
app/build.gradle
android {
...
productFlavors {
prod
mock {
applicationIdSuffix '.mock'
}
}
}
- 然后根据口味设置
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
- 最后在片段中使用
BaseFragment
别名:
class SomeFragment : BaseFragment() {
...
}
- 要使用
FragmentScenario
测试代码,请从 prod*
构建变体切换到 mock*
构建变体,并设置所有应该在测试中某处注入的依赖项 class(例如使用模拟)
拥有DaggerFragment
并测试片段的变体
- 创建您自己的
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)
}
- 扩展您的
DaggerFragment
实施并 设置片段 open
:
open class SomeFragment : DaggerFragment() {
...
}
- 为测试目的创建片段的另一个实现并覆盖
injectMembers
方法:
class TestSomeFragment : SomeFragment() {
override injectMembers() {
/* you can manually inject dependencies and mocks here */
}
}
- 在测试中使用
TestSomeFragment
。
我有一个简单的 Fragment
像这样:
class SomeFragment : DaggerFragment() {
...
}
现在我想使用 FragmentScenario
Fragment
class LoginFragmentTest {
@Test
fun test() {
launchFragmentInContainer<SomeFragment>()
onView(withId(R.id.someButton))
.check(matches(isDisplayed()))
}
}
但每次我尝试测试它总是:
java.lang.IllegalArgumentException: No injector was found for <...SomeFragment>
我怎样才能正确运行测试?有人可以帮我吗?
我找到了两种解决问题的方法:
- 使用单独的构建风格进行测试和
typealias
, - creating your own
DaggerFragment
and special test variants of your fragments
我认为第一种方法更简洁,建议使用它而不是后者,但我将描述这两种方法,以便您做出自己的选择。
使用 typealias
- 创建两种产品口味,
mock
和prod
:
app/build.gradle
android {
...
productFlavors {
prod
mock {
applicationIdSuffix '.mock'
}
}
}
- 然后根据口味设置
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
- 最后在片段中使用
BaseFragment
别名:
class SomeFragment : BaseFragment() {
...
}
- 要使用
FragmentScenario
测试代码,请从prod*
构建变体切换到mock*
构建变体,并设置所有应该在测试中某处注入的依赖项 class(例如使用模拟)
拥有DaggerFragment
并测试片段的变体
- 创建您自己的
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)
}
- 扩展您的
DaggerFragment
实施并 设置片段open
:
open class SomeFragment : DaggerFragment() {
...
}
- 为测试目的创建片段的另一个实现并覆盖
injectMembers
方法:
class TestSomeFragment : SomeFragment() {
override injectMembers() {
/* you can manually inject dependencies and mocks here */
}
}
- 在测试中使用
TestSomeFragment
。