如何解决在 Robolectric/Espresso 测试中避免睡眠
我正在使用 Robolectric 编写端到端测试,该测试触发对 OkHttp MockWebServer
的 HTTP 调用。它看起来像这样:
val mockServer = MockWebServer()
launchFragmentInHiltContainer<LoginFragment>()
onView(withId(R.id.loginEditText)).perform(typeText("loginId"))
onView(withId(R.id.loginButton)).perform(click())
// At this point,the fragment's viewmodel starts an HTTP request using Retrofit/OkHttp
// The callback causes a LiveData viewmodel to post an event,which the fragment listens
// to,and updates the UI accordingly
val request = mockServer.takeRequest()
assertEquals("/login",req.path)
Thread.sleep(1000)
shadowOf(getMainLooper()).idle()
// Without the two lines above,the test reaches this point before
// the mock server is done calling back
onView(withId(R.id.loggedInView)).check(matches(isdisplayed()))
如何确保在单击登录按钮后完全处理了服务器响应?
解决方法
我不是 100% 确定,但尝试一次
制作一个这样的对象
Object syncObject = new Object();
然后用这个替换你的 Thread.sleep(1000)
synchronized (syncObject) {
syncObject.notify();
}
如果它不能正常工作,那么用 wait() 代替 notify()。
,您可以使用 Espresso idling resources
(链接:Documentation)来实现这一点并摆脱那个根本不是一个好的选择的 Thread.sleep()
。
由于您使用的是 Okhttp
,因此已经有一个库可以为您解决问题:
Okhttp Idling Resource。
您不需要向代码中注入等待语句来检测请求的终止。
您可能很清楚,单独使用 Thread.sleep(X)
是解决此问题的非常糟糕的尝试,因为您的请求每次都需要更改,您可能会面临等待不够或等待太多的风险。
Idling Resources
是一种更好的尝试,但存在多个问题。
1)在每次检查队列是否为空(没有请求)之间,它让你等待 5 秒。当您执行大量测试时,这会很快堆积起来。
2)您需要更改您正在测试的代码以启用空闲资源。
3)它不适用于所有类型的异步请求。
我(和很多其他人)在 Espresso 中使用自定义重试功能来解决这个问题。
下面的函数检查条件是否成立,如果不成立,它会在 X 毫秒后再次检查。这样,您的测试将在请求完成后立即进行(而不是 IdlingResources 中的 5 秒等待时间)。您需要做的就是等待在您的请求被发送之前不成立的条件。
fun waitForCondition(matcher: Matcher<View>,timeout: Long = 15000L,condition: (View?) -> Boolean) {
require(timeout > 0) { "Require timeout>0" }
var success = false
lateinit var exception: NoMatchingViewException
val loopCounter = timeout / 250L
(0..loopCounter).forEach {
onView(matcher).check { view,noViewFoundException ->
if (condition(view)) {
success = true
return@check
} else {
Thread.sleep(250)
exception = noViewFoundException
}
}
if (success) {
return
}
}
throw exception
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。