reactjs - Kotlin JS 中的单元测试

标签 reactjs unit-testing kotlin-js

我在 Kotlin JavaScript 中有一个使用 React 的简单项目。我已经添加了单元测试,但是当我运行它们时,它们似乎调用了生产代码的 main 方法,并在尝试访问不存在的 DOM 结构时在初始化时失败。尽管被测试的类没有以任何方式引用 React 或 DOM。

从 Intelij IDEA 或通过 gradlew build 运行时,错误看起来相同(为了清楚起见,我用/APP/替换了我项目的完整路径):

Testing started at 17:51 ...
> Task :cleanBrowserTest
> Task :packageJson UP-TO-DATE
> Task :testPackageJson UP-TO-DATE
> Task :kotlinNodeJsSetup SKIPPED
> Task :kotlinNpmInstall
> Task :compileKotlinJs
> Task :processResources
> Task :mainClasses
> Task :compileTestKotlinJs
> Task :testProcessResources NO-SOURCE
> Task :testClasses

> Task :browserTest

(...)

Error: Target container is not a DOM element.

    at render (http://localhost:9876/absoluteD:/APP/build/js/packages/example-test/adapter-browser.js?92ccabfdcfa982960828b65b2f4e2683080859b4:25359:13)

    at render_0 (http://localhost:9876/absoluteD:/APP/build/js/packages/example-test/adapter-browser.js?92ccabfdcfa982960828b65b2f4e2683080859b4:29868:5)

    at main (http://localhost:9876/absoluteD:/APP/build/js/packages/example-test/adapter-browser.js?92ccabfdcfa982960828b65b2f4e2683080859b4:146311:5)

    at Object.<anonymous> (http://localhost:9876/absoluteD:/APP/build/js/packages/example-test/adapter-browser.js?92ccabfdcfa982960828b65b2f4e2683080859b4:146315:3)

    at http://localhost:9876/absoluteD:/APP/build/js/packages/example-test/adapter-browser.js?92ccabfdcfa982960828b65b2f4e2683080859b4:146289:37

    at Object.../example/kotlin/example.js (http://localhost:9876/absoluteD:/APP/build/js/packages/example-test/adapter-browser.js?92ccabfdcfa982960828b65b2f4e2683080859b4:146292:2)

    at __webpack_require__ (http://localhost:9876/absoluteD:/APP/build/js/packages/example-test/adapter-browser.js?92ccabfdcfa982960828b65b2f4e2683080859b4:20:30)

    at http://localhost:9876/absoluteD:/APP/build/js/packages/example-test/adapter-browser.js?92ccabfdcfa982960828b65b2f4e2683080859b4:146346:134

    at Object../kotlin/example-test.js (http://localhost:9876/absoluteD:/APP/build/js/packages/example-test/adapter-browser.js?92ccabfdcfa982960828b65b2f4e2683080859b4:146351:2)

    at __webpack_require__ (http://localhost:9876/absoluteD:/APP/build/js/packages/example-test/adapter-browser.js?92ccabfdcfa982960828b65b2f4e2683080859b4:20:30)

HeadlessChrome 81.0.4044 (Windows 10.0.0) ERROR

  Uncaught Error: Target container is not a DOM element.

  at d:/APP/build/js/node_modules/react-dom/cjs/react-dom.development.js:24828:1 <- D:/APP/build/js/packages/example-test/adapter-browser.js:25359:7

(...)


> Task :browserTest FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':browserTest'.
> command 'C:\Users\Arsen\.gradle\nodejs\node-v12.14.0-win-x64\node.exe' exited with errors (exit code: 1)

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 10s
8 actionable tasks: 6 executed, 2 up-to-date

最小的例子:

./build.gradle.kts
plugins {
    id("org.jetbrains.kotlin.js") version "1.3.70-eap-184"
}

group = "org.example"
version = "1.0-SNAPSHOT"

repositories {
    maven { setUrl("https://dl.bintray.com/kotlin/kotlin-eap") }
    maven("https://kotlin.bintray.com/kotlin-js-wrappers/")
    mavenCentral()
    jcenter()
}

dependencies {
    implementation(kotlin("stdlib-js"))

    implementation("org.jetbrains:kotlin-react:16.13.0-pre.94-kotlin-1.3.70")
    implementation("org.jetbrains:kotlin-react-dom:16.13.0-pre.94-kotlin-1.3.70")
    implementation(npm("react", "16.13.1"))
    implementation(npm("react-dom", "16.13.1"))
    testImplementation(kotlin("test-js"))
}

kotlin.target.browser {
}

./settings.gradle.kts
pluginManagement {
    repositories {
        maven { setUrl("https://dl.bintray.com/kotlin/kotlin-eap") }

        mavenCentral()

        maven { setUrl("https://plugins.gradle.org/m2/") }
    }
}
rootProject.name = "example"

./src/main/resources/index.html
<!doctype html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
        <div id="root"></div>
        <script src="example.js"></script>
    </body>
</html>

./src/main/kotlin/Main.kt
import react.dom.*
import kotlin.browser.document

fun main(args: Array<String>) {
    render(document.getElementById("root")) {

    }
}

./src/main/kotlin/DummyClass.kt
class DummyClass {
    fun foo(): String {
        return "foo"
    }
}

./src/test/kotlin/ExampleTest.kt
import kotlin.test.*

class ExampleTest {
    @Test
    fun foo() {
        assertEquals(DummyClass().foo(), "foo")
    }
}

如果我根本不引用生产代码(从测试中删除 DummyClass().foo()),或者当 main 方法不调用 render(document.getElementById("root")) 时,则不会发生该错误。 .

PS:如果重要,我在 Windows 上运行代码

最佳答案

这不是正确的答案 - 而是会立即解锁您的东西。

This回答指出

the test environment doesn't supply the DOM with an app id.



我们的测试框架也是如此——它没有提供 ID 为“root”的元素。
这让我相信 main/resources/index.html测试框架没有使用。异常跟踪确认 - 注意它是如何从 __webpack_require__ 开始的

理想的解决方案是让 karma 或 webpack 为我们的代码提供正确的 index.html;但我不知道如何做到这一点。

在此期间,您可以
  • 删除 <div id="root"></div>作为 index.html 的一部分
  • 让您的 kotlin 代码生成它,如下所示:

    ./src/main/kotlin/Main.kt
  • fun main(args: Array<String>) {
        document.body!!.insertAdjacentHTML("afterbegin", "<div id='root'></div>" )
        render(document.getElementById("root")) {
    
        }
    }
    

    希望有帮助

    关于reactjs - Kotlin JS 中的单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61839800/

    相关文章:

    javascript - 使用 React 扩展运算符在数组中设置 State

    javascript - ReactJS中如何处理两个setState方法依次执行?

    python - 'pytest' 退出时没有错误,但出现 "collected 0 items"

    javascript - 如何将 Kotlin 编译成 TypeScript?

    javascript - 替换测试中的特定模块

    javascript - React Navigation 检查上一个屏幕是否存在

    javascript - Jasmine angularjs - 监视 Controller 初始化时调用的方法

    python - Monkey-patch 由大量文件导入的模块(单元测试)

    javascript - Kotlin JS 不会在需要的地方添加 "new"关键字

    gradle - 插件如何提供扩展任务?