android - 没有接口(interface)方法 isAsyncStarted() 错误在魅族设备上运行 wiremock android 测试

标签 android wiremock android-instrumentation meizu

我有一个执行网络请求的 Android 应用程序。我在应用程序中使用 wiremock 进行仪器测试和改造。

请求被模拟成这样:

        stubFor(
            get(urlMatching("/hello/world"))
                .willReturn(
                    aResponse()
                        .withStatus(HttpURLConnection.HTTP_OK)
                        .withHeader("Content-Type", "text/plain")
                        .withBody(expectedServerResponse)
                )
        )

retrofit 界面:

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 个字符),并且测试是在魅族 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)

最佳答案

问题是wiremock和魅族都嵌入了javax.servlet类,但是版本不同(不兼容)。一种解决方法是重新定位(更改包名称)wiremock 嵌入的 javax.servlet 类。

而不是像这样包含 wiremock:

androidTestImplementation "com.github.tomakehurst:wiremock-standalone:2.23.2"

使用 gradle shadow 插件并改用 shadowed jar:

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

项目的 PR 实现了这个答案:https://github.com/libon/WiremockMeizuError/pull/1

关于android - 没有接口(interface)方法 isAsyncStarted() 错误在魅族设备上运行 wiremock android 测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56958824/

相关文章:

java - 在 fragment 中绘制多层矩形

java - 如何在 Wiremock Servlet 上启用响应模板?

java - 使用 wiremock 时连接被拒绝

java - 等待回调而不阻塞主线程

android - 尝试运行 jetpack compose 仪器测试时如何克服此构建错误

java - 定义应用程序中使用的常量的最佳实践

c# - 如何删除xamarin形式的操作栏?

android - 图像未使用 Html.fromhtml 在 TextView 中显示

java - Wiremock Stand alone - 如何使用请求数据操作响应

android - 仪器测试 : define a test as mandatory for the following