I have a simple Fragment
like so:
class SomeFragment : DaggerFragment() {
...
}
Now I want to test this Fragment
using FragmentScenario
class LoginFragmentTest {
@Test
fun test() {
launchFragmentInContainer<SomeFragment>()
onView(withId(R.id.someButton))
.check(matches(isDisplayed()))
}
}
But everytime I try to the test its always:
java.lang.IllegalArgumentException: No injector was found for <...SomeFragment>
How can I properly run the test? Can anybody help me here?
I found two ways to solve the problem:
typealias
,DaggerFragment
and special test variants of your fragmentsI consider the first approach cleaner and would recommend to use it rather than the latter, but I'll describe both of them, so you can make your own choice.
Build flavors with typealias
mock
and prod
:app/build.gradle
android {
...
productFlavors {
prod
mock {
applicationIdSuffix '.mock'
}
}
}
typealias
depending on the flavor, let's call it BaseFragment
:prod
flavor,
app/src/prod/com.example.mypackage/BaseFragment.kt
typealias BaseFragment = DaggerFragment
mock
flavor, app/src/mock/com.example.mypackage/BaseFragment.kt
typealias BaseFragment = Fragment
BaseFragment
alias in your fragments:class SomeFragment : BaseFragment() {
...
}
FragmentScenario
switch from the prod*
build variant to the mock*
one and set all the dependencies that are supposed to be injected somewhere in your test class (e.g. using mocks)Own DaggerFragment
and test variants of the fragments
DaggerFragment
(based on the actual dagger.android.support.DaggerFragment
implementation):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
implementation and set the fragment open
:open class SomeFragment : DaggerFragment() {
...
}
injectMembers
method:class TestSomeFragment : SomeFragment() {
override injectMembers() {
/* you can manually inject dependencies and mocks here */
}
}
TestSomeFragment
in your tests.