gpt4 book ai didi

android-fragments - 在 UI 测试中的片段内显示对话框(对话框片段)

转载 作者:行者123 更新时间:2023-11-28 21:35:39 25 4
gpt4 key购买 nike

我正在为片段编写 UI 测试用例。我正在使用 launchFragmentInContainer 来启动独立于事件的片段。

场景是,点击一个按钮,应该显示一个对话框片段,但是当我这样做时,屏幕上什么也没有出现。

这是我的主要片段

    package com.cbre.host.onboarding.locationaccess

import android.Manifest
import android.content.pm.PackageManager
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.activity.OnBackPressedCallback
import androidx.navigation.fragment.findNavController
import com.airbnb.mvrx.fragmentViewModel
import com.airbnb.mvrx.withState
import com.cbre.host.common.AppNavigator
import com.cbre.host.common.BaseFragment
import com.cbre.host.common.utils.Constants
import com.cbre.host.core.permission.PermissionProvider
import com.cbre.host.onboarding.R
import com.cbre.host.onboarding.databinding.LocationAccessFragmentBinding
import kotlinx.android.synthetic.main.location_access_fragment.*
import org.koin.android.ext.android.inject

class LocationAccessFragment : BaseFragment() {

private lateinit var binding: LocationAccessFragmentBinding
private val _viewModel: LocationAccessViewModel by fragmentViewModel()
private val _permissionProvider: PermissionProvider by inject()
private val _appNavigator: AppNavigator by inject()


override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = LocationAccessFragmentBinding.inflate(inflater, container, false)
binding.lifecycleOwner = viewLifecycleOwner
return binding.root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
requireActivity().onBackPressedDispatcher.addCallback(
viewLifecycleOwner,
object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
// DO NOTHING
}
})

may_be_later.setOnClickListener { findNavController().navigate(R.id.next_action_a) }
access_location.setOnClickListener { handleLocationAccessPermission() }
tv_privacy_notice.setOnClickListener {
_appNavigator.openInChrome(
context!!,
Constants.PRIVACY_URL
)
}
}

override fun invalidate() = withState(_viewModel) { state ->
binding.run {
buttonOneText = state.onBoardingContent.button1Text
buttonTwoText = state.onBoardingContent.button2Text
imageHelpText = state.onBoardingContent.imageHelpText
imageText = state.onBoardingContent.imageText
imageUrl = state.onBoardingContent.imageUrl
}
}

private fun handleLocationAccessPermission() = activity?.let {
_permissionProvider.checkSelfPermission(
it,
permission = Manifest.permission.ACCESS_FINE_LOCATION,
requestPermission = { requestPermission() },
granted = {
findNavController().navigate(R.id.next_action_b)
},
shouldShowExplanation = { showDialog() })
}

private fun showDialog() {
val fm = fragmentManager
fm ?: return
val dialogFragment = LocationAccessDialogFragment.newInstance()
dialogFragment.show(fm, "locationAccessDialog")
dialogFragment.callback = object : LocationAccessDialogFragment.Callback {
override fun onAllow() {
requestPermission()
}
}
}

override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
when (requestCode) {
PermissionProvider.REQUEST_CODE -> {
if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
findNavController().navigate(R.id.next_action_b)
}
}
}
}

private fun requestPermission() = requestPermissions(
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
PermissionProvider.REQUEST_CODE
)
}

这是我的对话片段

package com.cbre.host.onboarding.locationaccess

import android.app.AlertDialog
import android.app.Dialog
import android.os.Bundle
import android.view.LayoutInflater
import androidx.fragment.app.DialogFragment
import com.cbre.host.onboarding.databinding.LocationAccessDialogBinding


class LocationAccessDialogFragment : DialogFragment() {

private lateinit var binding: LocationAccessDialogBinding
var callback: Callback? = null

interface Callback {
fun onAllow()
}

companion object {
fun newInstance() = LocationAccessDialogFragment()
}

override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
binding =
LocationAccessDialogBinding.inflate(LayoutInflater.from(activity), null, false)
val builder = AlertDialog.Builder(activity)
.setView(binding.root)

val d = builder.create()

d?.window?.decorView?.setBackgroundResource(android.R.color.transparent)

binding.dontAllow.setOnClickListener {
this.dismiss()
}

binding.allow.setOnClickListener {
callback?.onAllow()
this.dismiss()
}
return d
}
}

这是我的测试

@Test
fun a_checkBtnAccessLocationClickForDenyPermission() {
val scenario = launchFragmentInContainer<LocationAccessFragment>()
scenario.onFragment { fragment ->
Navigation.setViewNavController(fragment.requireView(), navController)
}

onView(withId(R.id.access_location)).perform(click())
}
}

最佳答案

我假设您想要对 Fragment 执行单元测试,在这种情况下,您应该对 DialogFragment 执行单独的单元测试。

片段单元测试看起来像这样。

@Test
fun a_checkBtnAccessLocationClickForDenyPermission() {
val mockNavController = mock(NavController::class.java)
val scenario = launchFragmentInContainer<LocationAccessFragment>()
scenario.onFragment { fragment ->
Navigation.setViewNavController(fragment.requireView(), mockNavController)
}

onView(withId(R.id.access_location)).perform(ViewActions.click())
verify(mockNavController).navigate(R.id.actoin_fragment_to_locationAccessDialog)

}
}

对话框单元测试,对话框不会加载 launchFragmentInContainer,因此您需要使用 launchFragment

@Test
fun positiveButton() {

launchFragment(themeResId = R.style.My_theme) {
return@launchFragment LocationAccessDialogFragment()
}

onView(allOf(withId(android.R.id.button1), withText(R.string.confirm)))
.inRoot(isDialog())
.check(matches(isDisplayed()))
.perform(ViewActions.click())

}

关于android-fragments - 在 UI 测试中的片段内显示对话框(对话框片段),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59045001/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com