android studio 3.4
dagger-android 2.19
我正在尝试测试我的Activity,我想使用匕首将模拟从单元测试注入到Activity中。
我有一个简单的ForecastActivity
class ForecastActivity : AppCompatActivity() {
@Inject
lateinit var locationUtils: LocationUtils
override fun onCreate(savedInstanceState: Bundle?) {
AndroidInjection.inject(this)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_home)
if(locationUtils.isLocationServicesEnabled(this)) {
locationUtils.getLocationCoordinates(this)
}
else {
startRetryFragment()
}
}
}
问题是我想注入LocationUtils的模拟物。
我有一个Dagger模块,该模块返回用于我的单元测试的模拟:
@Module
class ActivityTestModule {
@Reusable
@Provides
fun provideLocationUtils(): LocationUtils = mock()
}
和一个组件:
@Singleton
@Component(modules = [ActivityTestModule::class])
interface TestComponent {
fun inject(forecastActivityTest: ForecastActivityTest)
}
我有一个测试应用程序类,用于扩展ForecastApplication
class TestApplication : ForecastApplication() {
private lateinit var testComponent: TestComponent
override fun onCreate() {
super.onCreate()
testComponent = DaggerTestComponent
.builder()
.build()
}
fun getTestComponent() = testComponent
}
对于实际的单元测试,我有以下内容,但存在许多错误,并且代码无法正常工作。我在我认为问题所在的地方发表了评论:
@RunWith(AndroidJUnit4::class)
class ForecastActivityTest {
private lateinit var forecastActivityScenario: ActivityScenario<ForecastActivity>
@Inject
lateinit var locationUtils: LocationUtils
@Before
fun setUp() {
/* Cast error that cannot be cast to a ForecastApplication */
val testApplication = getApplicationContext<ForecastApplication>() as TestApplication
testApplication.getTestComponent()
.inject(this)
forecastActivityScenario = ActivityScenario.launch(ForecastActivity::class.java)
/* Want to stub this locationUtils, as the real implementation passes in instance of the ForecastActivity I don't think will work. Just wondering is it better to use `any()` instead for `isLocationServiceEnabled(any())` */
whenever(locationUtils.isLocationServicesEnabled(any())).thenReturn(true)
forecastActivityScenario.moveToState(Lifecycle.State.DESTROYED)
assertThat(locationUtils).isNotNull
}
@Test
fun `forecastActivityScenario should not be null`() {
assertThat(forecastActivityScenario).isNotNull
forecastActivityScenario = ActivityScenario.launch(ForecastActivity::class.java)
forecastActivityScenario.moveToState(Lifecycle.State.CREATED)
}
}
我还修改了设置,以尝试使用以下方法使其正常工作。但是,模拟LocationUtils是在ForecastActivityTest中创建的,但在ForecastActivity中,匕首注入的是实际实现,而不是单元测试中的模拟,因此whenever(locationUtils.isLocationServicesEnabled(any())).thenReturn(true)
可以正常工作。
@Before
fun setUp() {
DaggerTestComponent
.builder()
.build()
.inject(this)
forecastActivityScenario = ActivityScenario.launch(ForecastActivity::class.java)
whenever(locationUtils.isLocationServicesEnabled(any())).thenReturn(true)
forecastActivityScenario.moveToState(Lifecycle.State.DESTROYED)
assertThat(locationUtils).isNotNull
}
在此先感谢
我仅从单元测试方面展示了匕首实现。否则问题将太长了