我正在尝试将 WireMock 集成到基于 JUnit/Espresso/Kaspresso 的 Android 自动测试中 我不需要模拟请求,我只想验证传出的请求
构建.gradle:
androidTestImplementation "com.github.tomakehurst:wiremock-jre8-standalone:2.35.1"
测试班:
val wireMockRule: WireMockRule = WireMockRule(8888)
@get:Rule
open val ruleChain: RuleChain = RuleChain
.outerRule(grantPermissionRule)
.around(wireMockRule)
.around(activityRule)
@Test
fun testWiremock() {
val url = "http://google.com"
val client = OkHttpClient()
val request = Request.Builder().url(url).build();
val response = client.newCall(request).execute()
assertNotNull("just to make sure there is a valid response for this simple request", response.body!!.string())
verify(anyRequestedFor(UrlPattern.ANY))
}
结果:
com.github.tomakehurst.wiremock.client.VerificationException: Expected at least one request matching: {
"method" : "ANY"
}
Requests received: [ ]
由于this问题,我没有使用最新版本的WireMock。
还在 Android 13 上尝试了不同的模拟器(API 26 和 34)和真实设备 看起来我忘记了一些东西,但不明白它是什么。请帮忙
如果您的应用程序使用 OkHttp(根据您尝试实现的代码判断),您根本不需要 WireMock!您可以创建自定义拦截器并将其注册到您的 OkHttp 应用程序实例上,并捕获稍后可以验证的请求。你可以查看我已经完成的这个我已经有一段时间没有使用的旧实现了——你当然可以根据你的需要定制它,但它可以帮助你开始
private val capturedRequests = mutableListOf<CapturedRequest>()
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
val url = request.url.toString()
val queryParams = extractQueryParams(request.url)
val method = request.method
val headers = request.headers.names().associateWith { request.header(it)!! }
val requestBody = request.body
val buffer = Buffer()
requestBody?.writeTo(buffer)
val body = if (requestBody != null) buffer.readUtf8() else null
capturedRequests.add(CapturedRequest(url, queryParams, method, headers, body))
return chain.proceed(request)
}
private fun extractQueryParams(url: HttpUrl): Map<String, String> {
val queryParamNames = url.queryParameterNames
val queryParamsMap = mutableMapOf<String, String>()
queryParamNames.forEach { name ->
val value = url.queryParameter(name) // Retrieves the first value for the name
if (value != null) {
queryParamsMap[name] = value
}
}
return queryParamsMap.toMap()
}
fun hasRequestWithPath(path: String) {
capturedRequests.forEach { request ->
if (request.url.contains(path)) {
return
}
}
throw Exception("There is no request containing `$path` in the list of captured requests")
}
fun getRequestWithPath(path: String): CapturedRequest? {
capturedRequests.forEach { request ->
if (request.url.contains(path)) {
return request
}
}
return null
}
fun getCapturedRequests(): List<CapturedRequest> {
return capturedRequests
}
fun clearCapturedRequests() {
capturedRequests.clear()
}
}
然后,您可以在应用程序代码中添加某种配置器,允许您从 Espresso 测试中设置拦截器的实例,例如:
@TestOnly
object OkHttpClientTestConfigurator {
var espressoInterceptor: Interceptor? = null
}
然后有条件地将其应用到 OkHttp 客户端构建器中,例如
OkHttpClientTestConfigurator.espressoInterceptor?.let {
okHttpClientBuilder.addInterceptor(it)
}