Нет метода интерфейса isAsyncStarted() Ошибка при выполнении тестов Android Wiremock на устройстве Meizu
У меня есть приложение для Android, которое выполняет сетевой запрос. Я использую Wiremock для инструментальных испытаний и модернизации в приложении.
Запрос смоделирован так:
stubFor(
get(urlMatching("/hello/world"))
.willReturn(
aResponse()
.withStatus(HttpURLConnection.HTTP_OK)
.withHeader("Content-Type", "text/plain")
.withBody(expectedServerResponse)
)
)
Модифицированный интерфейс:
interface HelloWorldService {
@GET("/hello/world")
fun getHelloWorld(): Call<ResponseBody>
}
Код приложения, выполняющего запрос:
val helloWorldService =
Retrofit.Builder()
.baseUrl(intent.getStringExtra(EXTRA_BASE_URL))
.client((application as MyApplication).createRetrofitHttpClient())
.build()
.create(HelloWorldService::class.java)
helloWorldService.getHelloWorld().enqueue(object : Callback<ResponseBody> {
override fun onResponse(call: Call<ResponseBody>, response: Response<ResponseBody>) {
textView.text = if (response.isSuccessful) {
response.body()?.string()
} else {
response.message()
}
}
override fun onFailure(call: Call<ResponseBody>, t: Throwable) {
textView.text = t.message
}
})
Когда длина содержимого смоделированного ответа велика (более 256 символов), и тест выполняется на Meizu Note 5, wiremock находит ответ и выглядит так, как будто он собирается отправить 200
ответ, как я вижу это в журнале logcat:
Matched response definition:
{
"status" : 200,
"body" : "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"headers" : {
"Content-Type" : "text/plain"
}
}
Response:
HTTP/1.1 200
Content-Type: [text/plain]
Matched-Stub-Id: [a45b21c9-95f6-45fa-a7c3-acf473485fb6]
Тем не менее, приложение на самом деле получает 500
код ошибки, с этим сообщением в ответе об ошибке:
No interface method isAsyncStarted()Z in class Ljavax/servlet/http/HttpServletRequest; or its super classes (declaration of 'javax.servlet.http.HttpServletRequest' appears in /system/framework/meizu2_jcifs.jar)
1 ответ
Проблема заключается в том, что wiremock и meizu оба вставляют javax.servlet
классы, но разные (несовместимые) версии. Одним из обходных путей для этого является перемещение (изменение имен пакетов) javax.servlet
классы, встроенные в Wiremock.
Вместо включения Wiremock, как это:
androidTestImplementation "com.github.tomakehurst:wiremock-standalone:2.23.2"
Используйте плагин gradle shadow и используйте затененный кувшин вместо:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.github.jengelman.gradle.plugins:shadow:5.1.0'
}
}
apply plugin: com.github.jengelman.gradle.plugins.shadow.ShadowPlugin
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
android {
dependencies {
shadow "com.github.tomakehurst:wiremock-standalone:2.23.2"
androidTestImplementation files("$buildDir/libs/shadow.jar")
}
}
tasks.configureEach { theTask ->
def taskName = theTask.name.toString()
if (taskName =~ /generate.*Sources/) {
theTask.dependsOn tasks.named("shadowJar")
}
}
tasks.register("shadowJar", ShadowJar) {
baseName = 'shadow'
configurations = [project.configurations.shadow]
relocate ('javax.servlet', 'com.example.wiremockexample.javax.servlet'){}
}
Полный пример проекта, объясняющего эту проблему более подробно, находится здесь: https://github.com/libon/WiremockMeizuError
И пиар проекта реализует этот ответ: https://github.com/libon/WiremockMeizuError/pull/1