gpt4 book ai didi

java - 如何通过espresso UI测试初始化​​presenter的可为空变量以避免NPE

转载 作者:行者123 更新时间:2023-12-02 04:44:47 24 4
gpt4 key购买 nike

我正在尝试使用 kotlin 为 Android 应用程序构建编写 Espresso UI 测试。我编写了一个基本的 UI 测试来测试 loginFragment 中存在的 UI 元素。

@LargeTest
class LoginFragmentTest {

private val serverUrl = "https://example.com"

@JvmField
var activityRule = ActivityTestRule(AuthenticationActivity::class.java, true, true)

@Rule
fun rule() = activityRule

@Before
fun setUp() {
rule().activity.addFragmentBackStack(ScreenViewEvent.Login.screenName, R.id.fragment_container) {
newInstance(serverUrl)
}
}


@Test
fun check_UI_elements(){
onView(withId(R.id.text_login)).check(matches(withText("Login")))
onView(withId(R.id.text_username_or_email)).check(matches(withHint("Username or email")))
onView(withId(R.id.text_password)).check(matches(withHint("Password")))
onView(withId(R.id.button_log_in)).check(matches(withText("Login")))
onView(withId(R.id.button_forgot_your_password)).check(matches(withText("Forgot your password?")))
}

登录 fragment

class LoginFragment : Fragment(), LoginView {
@Inject
lateinit var presenter: LoginPresenter
@Inject
lateinit var analyticsManager: AnalyticsManager
private var serverName: String? = null
private val editTextsDisposable = CompositeDisposable()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
AndroidSupportInjection.inject(this)

arguments?.run {
serverName = getString(SERVER_NAME)
}
}

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = container?.inflate(R.layout.fragment_authentication_log_in)

.....
}

登录演示者

class LoginPresenter @Inject constructor(
private val view: LoginView,
private val strategy: CancelStrategy,
private val navigator: AuthenticationNavigator,
private val tokenRepository: TokenRepository,
private val localRepository: LocalRepository,
private val settingsInteractor: GetSettingsInteractor,
private val analyticsManager: AnalyticsManager,
private val saveCurrentServer: SaveCurrentServerInteractor,
private val saveAccountInteractor: SaveAccountInteractor,
private val factory: RocketChatClientFactory,
val serverInteractor: GetConnectingServerInteractor
) {
// TODO - we should validate the current server when opening the app, and have a nonnull get()
private var currentServer = serverInteractor.get()!!
private val token = tokenRepository.get(currentServer)
private lateinit var client: RocketChatClient
private lateinit var settings: PublicSettings

fun setupView() {
setupConnectionInfo(currentServer)
setupForgotPasswordView()
}

...
}

我还有 SaveConnectingServerInteractor 和 GetConnectingServerInteractor,用于在身份验证时存储服务器 url。

open class SaveConnectingServerInteractor @Inject constructor(
@ForAuthentication private val repository: CurrentServerRepository
) {
fun save(url: String) = repository.save(url)
}
open class GetConnectingServerInteractor @Inject constructor(
@ForAuthentication private val repository: CurrentServerRepository
) {
fun get(): String? = repository.get()

fun clear() {
repository.clear()
}
}

登录 fragment 模块

@Module
class LoginFragmentModule {

@Provides
@PerFragment
fun loginView(frag: LoginFragment): LoginView = frag

@Provides
@PerFragment
fun provideLifecycleOwner(frag: LoginFragment): LifecycleOwner = frag
}

登录 fragment 提供程序

@Module abstract class LoginFragmentProvider {

@ContributesAndroidInjector(modules = [LoginFragmentModule::class])
@PerFragment
abstract fun provideLoginFragment(): LoginFragment
}

但是在运行测试时,我收到 KotlinNullPointerException,因为变量 currentServer 变为 null,因为其中没有保存 url。有什么办法可以避免它在运行 UI 测试期间为空。我尝试过使用 elvis 运算符并修改 LoginPresenter,但我想知道是否还有其他可行的方法。我只想使用任何 URL 字符串初始化当前服务器的值,以避免在运行测试期间出现 NPE。

我也尝试过使用

@Before
fun setUp() {
`when`(serverInteractor.get()).thenReturn("http://fakeurl")`
rule().activity.addFragmentBackStack(ScreenViewEvent.Login.screenName, R.id.fragment_container) {
newInstance(serverUrl)
}
}

但随后它就抛出了

java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.String chat.rocket.android.server.domain.CurrentServerRepository.get()' on a null object reference
at chat.rocket.android.server.domain.GetConnectingServerInteractor.get(GetConnectingServerInteractor.kt:9)
at chat.rocket.android.authentication.login.ui.LoginFragmentTest.setUp(LoginFragmentTest.kt:42)

最佳答案

我认为您应该将演示者的模拟版本注入(inject)到 fragment 中以进行测试。你可以按照这个: https://proandroiddev.com/writing-espresso-instrumentation-tests-with-dagger2-kotlin-d30f12c4769b或者只是文档: https://square.github.io/dagger/#using (模块覆盖)

关于java - 如何通过espresso UI测试初始化​​presenter的可为空变量以避免NPE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56493147/

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