Issue
Android Studio 3.5.1
Kotlin 1.3
I have the following method that I am trying to unit test. That uses the WebView
and WebViewClient
The method I have is the following that needs to be unit tested:
fun setPageStatus(webView: WebView?, pageStatus: (PageStatusResult) -> Unit) {
webView?.webViewClient = object : WebViewClient() {
override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
pageStatus(PageStatusResult.PageStarted(url ?: "", favicon))
}
override fun onPageFinished(view: WebView?, url: String?) {
pageStatus(PageStatusResult.PageFinished(url ?: ""))
}
}
}
I takes a webView that overrides some callback from the WebViewClient. And then calls a lambda function in the onPageStarted or onPageFinished.
Uses a sealed class to set the properties that is passed in the lambda method
sealed class PageStatusResult {
data class PageFinished(val url: String) : PageStatusResult()
data class PageStarted(val url: String, val favicon: Bitmap?) : PageStatusResult()
}
In the unit test I have do something like this:
@Test
fun `should set the correct settings of the WebView`() {
// Arrange the webView
val webView = WebView(RuntimeEnvironment.application.baseContext)
// Act by calling the setPageStatus
webFragment.setPageStatus(webView) { pageStatusResult ->
when(pageStatusResult) {
is PageStarted -> {
// Assert that the url is correct
assertThat(pageStatusResult.url).isEqualToIgnoringCase("http://google.com")
}
}
}
// Call the onPageStarted on the webViewClient and and assert in the when statement
webView.webViewClient.onPageStarted(webView, "http://google.com", null)
}
Solution
As the nature of this unit test is async, instead of calling the webView.webViewClient.onPageStarted
synchronously yourself, you should use an async testing approach. In this way, we pass a URL to the WebView
to show, then wait until the onPageStarted
method is called by the WebView
itself.
It seems that the best option to run async unit tests in Android is using the Awaitility.
build.gradle
dependencies {
testImplementation 'org.awaitility:awaitility:4.0.1'
}
Unit Test Class
@Test
fun `should set the correct settings of the WebView`() {
val requestedUrl = "https://www.google.com"
var resultUrl: String? = null
// Arrange the webView
val webView = WebView(RuntimeEnvironment.application.baseContext)
// Act by calling the setPageStatus
webFragment.setPageStatus(webView) { pageStatusResult ->
when (pageStatusResult) {
is PageStatusResult.PageStarted -> {
resultUrl = pageStatusResult.url
}
}
}
// trying to load the "requestedUrl"
webView.loadUrl(requestedUrl)
// waiting until the "onPageStarted" is called
await().until { resultUrl != null }
// now check the equality of URLs
assertThat(resultUrl).isEqualToIgnoringCase(requestedUrl)
}
Answered By - aminography
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.