在我们的 Android 应用程序中,我们使用 Google Maps API 来显示用户位置。目前我们正在使用 Koin 来提供 FusedLocationProviderClient 依赖项的参数化注入(它需要一个活动)到我们的 Fragment 类中。从理论上讲,这应该使测试和模拟 Client 类(使用 mockk)更加直接。然而,在尝试使用 Android FragmentScenario 运行测试时,测试似乎在某处陷入无限循环(调试没有给出原因的答案)。 有没有人对如何与我们正在使用的框架一起测试它有任何进一步的想法。 Android/Google 文档没有提供任何帮助,也没有提供大量的网络拖网时间。
我们尝试在注入和不注入 FusedLocationProvideClient 的情况下进行测试。我们已经尝试在我们的测试类中启动 Koin 测试模块,使用活动参数化和不使用活动参数化,似乎没有什么不同。 FusedLocationProviderClient 被模拟为 relaxed 设置为 true。
测试班:
private val viewModel = mockk<LocationSelectionViewModel>(relaxed = true)
private val locationClient = mockk<FusedLocationProviderClient>(relaxed = true)
override var testModule = module {
viewModel { viewModel }
factory { locationClient }
}
@Test
fun itShouldDoSomethingWithLocation() {
val scenario = FragmentScenario.launchInContainer(LocationSelectionDialogFragment::class.java)
scenario.moveToState(Lifecycle.State.RESUMED)
scenario.onFragment {
val location = Location("this")
location.latitude = 37.422
location.longitude = -122.084
location.accuracy = 3.0f
locationClient.setMockMode(true)
locationClient.setMockLocation(location)
verify { viewModel.onDisplayed() }
}
}
片段类:
class LocationSelectionDialogFragment: AbstractBottomSheetFragment(), KoinComponent, TestSupportDatabindingInterface, OnMapReadyCallback {
private lateinit var _dataBinding: ViewDataBinding
override fun dataBinding(): ViewDataBinding? = _dataBinding
private val viewModel: LocationSelectionViewModel by viewModel()
//Ma Objects n Variables
private val LOCATION_PERMISSION = 42
private lateinit var map: GoogleMap
private var mapView: MapView? = null
private val fusedLocationClient: FusedLocationProviderClient by inject { parametersOf(activity!!) }
private lateinit var locationCallback: LocationCallback
陷入无限循环
如果您试图模拟
Task<Location>
返回的 FusedLocationProviderClient
对象之一,并且您的应用程序代码使用协程并调用该任务的 await()
方法,那么您需要使用静态模拟:
mockkStatic("kotlinx.coroutines.tasks.TasksKt")
该文件中还有其他几种
Task
扩展方法,因此这也应该解决与那些类似的情况。