Kotlin JS Karma测试无法发起HTTP请求问题排查
用Karma运行Kotlin/JS测试时无法发起HTTP请求的问题解决
问题
在使用Karma运行Kotlin/JS测试时,无论是通过Ktor Client还是直接调用window.fetch发起HTTP请求,都报错TypeError: Failed to fetch,无法成功请求外部接口。
相关配置与代码
Gradle配置(build.gradle.kts)
js(IR) { useCommonJs() browser { testTask { useKarma { useChromeHeadless() } } } binaries.executable() }
Ktor Client请求代码
val text = HttpClient(Js).get("https://www.google.com/") { header("Content-Type", "text/html; charset=utf-8") header("Accept", "*/*") }.body<String>()
对应错误日志
> Task :jsTestClasses > Task :compileTestDevelopmentExecutableKotlinJs > Task :jsTestTestDevelopmentExecutableCompileSync > Task :jsBrowserTest myTest before fetch TRACE: Adding Accept-Charset=UTF-8 to https://www.google.com/TRACE: Processing exception Error_0: Fail to fetch for request https://www.google.com/Error_0: Fail to fetch at http://localhost:9876/absolute/var/folders/cb/nd4gn6pn79zg52rz_l5bl1bdjfnmjy/T/_karma_webpack_293805/commons.js?58a2b80ce49dc5767b060dfe37192606438b082a:52793:26 Caused by: TypeError: Failed to fetch at commonFetch (http://localhost:9876/absolute/var/folders/cb/nd4gn6pn79zg52rz_l5bl1bdjfnmjy/T/_karma_webpack_293805/commons.js?58a2b80ce49dc5767b060dfe37192606438b082a:52730:13) at $executeCOROUTINE$16.doResume_5yljmg_k$ (http://localhost:9876/absolute/var/folders/cb/nd4gn6pn79zg52rz_l5bl1bdjfnmjy/T/_karma_webpack_293805/commons.js?58a2b80ce49dc5767b060dfe37192606438b082a:52105:29) at JsClientEngine.execute_95skru_k$ (http://localhost:9876/absolute/var/folders/cb/nd4gn6pn79zg52rz_l5bl1bdjfnmjy/T/_karma_webpack_293805/commons.js?58a2b80ce49dc5767b060dfe37192606438b082a:52224:16) at HttpClientEngine$executeWithinCallContext$slambda.doResume_5yljmg_k$ (http://localhost:9876/absolute/var/folders/cb/nd4gn6pn79zg52rz_l5bl1bdjfnmjy/T/_karma_webpack_293805/commons.js?58a2b80ce49dc5767b060dfe37192606438b082a:46100:44) at HttpClientEngine$executeWithinCallContext$slambda.invoke_1yhb3o_k$ (http://localhost:9876/absolute/var/folders/cb/nd4gn6pn79zg52rz_l5bl1bdjfnmjy/T/_karma_webpack_293805/commons.js?58a2b80ce49dc5767b060dfe37192606438b082a:46082:16) at l (http://localhost:9876/absolute/var/folders/cb/nd4gn6pn79zg52rz_l5bl1bdjfnmjy/T/_karma_webpack_293805/commons.js?58a2b80ce49dc5767b060dfe37192606438b082a:46133:16) at _no_name_provided__qut3iv_6.doResume_5yljmg_k$ (http://localhost:9876/absolute/var/folders/cb/nd4gn6pn79zg52rz_l5bl1bdjfnmjy/T/_karma_webpack_293805/commons.js?58a2b80ce49dc5767b060dfe37192606438b082a:31198:43) at CoroutineImpl.resumeWith_7onugl_k$ (http://localhost:9876/absolute/var/folders/cb/nd4gn6pn79zg52rz_l5bl1bdjfnmjy/T/_karma_webpack_293805/commons.js?58a2b80ce49dc5767b060dfe37192606438b082a:31062:33) at CoroutineImpl.resumeWith_s3a3yh_k$ (http://localhost:9876/absolute/var/folders/cb/nd4gn6pn79zg52rz_l5bl1bdjfnmjy/T/_karma_webpack_293805/commons.js?58a2b80ce49dc5767b060dfe37192606438b082a:31108:17) at DispatchedTask.run_mw4iiu_k$ (http://localhost:9876/absolute/var/folders/cb/nd4gn6pn79zg52rz_l5bl1bdjfnmjy/T/_karma_webpack_293805/commons.js?58a2b80ce49dc5767b060dfe37192606438b082a:41652:24)
尝试window.fetch的代码
val response = window.fetch(url).await() println("response: ${response.body}")
对应错误日志
> Task :jsTestTestDevelopmentExecutableCompileSync > Task :jsBrowserTest getFileText before fetch TypeError: Failed to fetch TypeError: Failed to fetch at 2.doResume_5yljmg(/var/folders/cb/nd4gn6pn79zg52rz_l5bl1bdjfnmjy/T/_karma_webpack_124481/commons.js:3883) at <global>.httpGet(/var/folders/cb/nd4gn6pn79zg52rz_l5bl1bdjfnmjy/T/_karma_webpack_124481/commons.js:3765) at 1.doResume_5yljmg(/var/folders/cb/nd4gn6pn79zg52rz_l5bl1bdjfnmjy/T/_karma_webpack_124481/commons.js:3845) at HtmlResourceLoader.getFileText_6u54xq(/var/folders/cb/nd4gn6pn79zg52rz_l5bl1bdjfnmjy/T/_karma_webpack_124481/commons.js:3920) at slambda.doResume_5yljmg(/var/folders/cb/nd4gn6pn79zg52rz_l5bl1bdjfnmjy/T/_karma_webpack_124481/commons.js:992) at slambda.invoke_pbb09x(/var/folders/cb/nd4gn6pn79zg52rz_l5bl1bdjfnmjy/T/_karma_webpack_124481/commons.js:978) at slambda.$block(/var/folders/cb/nd4gn6pn79zg52rz_l5bl1bdjfnmjy/T/_karma_webpack_124481/commons.js:1023) at slambda.doResume_5yljmg(/var/folders/cb/nd4gn6pn79zg52rz_l5bl1bdjfnmjy/T/_karma_webpack_124481/commons.js:3792) at slambda.invoke_d6gbsu(/var/folders/cb/nd4gn6pn79zg52rz_l5bl1bdjfnmjy/T/_karma_webpack_124481/commons.js:3778) at <global>.l(/var/folders/cb/nd4gn6pn79zg52rz_l5bl1bdjfnmjy/T/_karma_webpack_124481/commons.js:3825)
解决方法
方法1:修改Chrome Headless启动参数
问题根源是Chrome Headless默认启用Web安全策略,限制了跨域请求。修改Karma配置,添加禁用Web安全的参数:
js(IR) { useCommonJs() browser { testTask { useKarma { useChromeHeadless { args("--disable-web-security", "--disable-features=VizDisplayCompositor") } } } } binaries.executable() }
方法2:改用Mock数据(推荐)
单元测试应避免依赖外部服务,可通过Mock模拟HTTP请求的返回结果,比如使用Ktor的MockEngine:
val client = HttpClient(MockEngine) { engine { addHandler { request -> respondText("Mocked response content", status = HttpStatusCode.OK) } } }
方法3:配置Karma代理
如果必须发起真实请求,可在Karma中配置代理,将请求转发到目标服务器,避免跨域问题:
useKarma { proxies = mapOf( "/api" to "https://www.google.com" ) }
然后测试代码中请求/api即可,Karma会自动转发到目标地址。
内容的提问来源于stack exchange,提问作者vovahost
相关产品推荐
相关产品推荐

