Gradle 7.3.3运行Junit无法创建TestEngine

the*_*ous 3 junit mockito powermock gradle

我正在使用 Gradle 7.3.3,但需要 JUnit 和 PowerMock

我已将 settings.gradle 配置为:

        version('spring', '5.3.15')
        alias('spring-test').to('org.springframework', 'spring-test').versionRef('spring')

        //https://mvnrepository.com/artifact/junit/junit
        version('junit', '4.13.2')
        alias('junit').to('junit', 'junit').versionRef('junit')

        //https://mvnrepository.com/artifact/org.mockito/mockito-core
        version('mockito', '3.12.4')
        alias('mockito').to('org.mockito', 'mockito-core').versionRef('mockito')

        //https://mvnrepository.com/artifact/org.powermock/powermock-api-mockito2
        version('powermock', '2.0.9')
        alias('powermock-api').to("org.powermock", "powermock-api-mockito2").versionRef('powermock')
        alias('powermock-api-support').to("org.powermock", "powermock-api-support").versionRef('powermock')
        alias('powermock-core').to("org.powermock", "powermock-core").versionRef('powermock')
        alias('powermock-module-junit4').to("org.powermock", "powermock-module-junit4").versionRef('powermock')
        alias('powermock-module-junit4-common').to("org.powermock", "powermock-module-junit4-common").versionRef('powermock')
        alias('powermock-reflect').to("org.powermock", "powermock-reflect").versionRef('powermock')

        bundle('test', ['junit', 'mockito', 'powermock-api', 'powermock-api-support', 'powermock-core', 'powermock-module-junit4', 'powermock-module-junit4-common', 'powermock-reflect', 'spring-test'])
Run Code Online (Sandbox Code Playgroud)

然后在模块的 build.gradle 中,我将其包含在内

dependencies {
    testImplementation libs.bundles.test
}

test {
    useJUnitPlatform()
}
Run Code Online (Sandbox Code Playgroud)

测试类如下

import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
public class MyTest {

    @Test
    public void test(){
        System.out.print("hello");
    }
}
Run Code Online (Sandbox Code Playgroud)

运行测试后,我得到了失败测试的报告,其中包含以下堆栈跟踪

org.gradle.api.internal.tasks.testing.TestSuiteExecutionException: Could not complete execution for Gradle Test Executor 6.
    at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:63)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
    at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
    at com.sun.proxy.$Proxy2.stop(Unknown Source)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
    at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
    at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:133)
    at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:71)
    at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
    at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)
Caused by: org.junit.platform.commons.PreconditionViolationException: Cannot create Launcher without at least one TestEngine; consider adding an engine implementation JAR to the classpath
    at org.junit.platform.commons.util.Preconditions.condition(Preconditions.java:296)
    at org.junit.platform.launcher.core.DefaultLauncher.<init>(DefaultLauncher.java:48)
    at org.junit.platform.launcher.core.LauncherFactory.create(LauncherFactory.java:105)
    at org.junit.platform.launcher.core.LauncherFactory.create(LauncherFactory.java:75)
    at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:97)
    at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:79)
    at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:75)
    at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:61)
    ... 18 more
Run Code Online (Sandbox Code Playgroud)

那么,我的配置出了什么问题,如何让这个东西与这个 gradle 版本一起工作呢?

Les*_*iak 5

您混合使用了 JUnit5 和 JUnit4,这需要额外注意配置。

解释:

test {
    useJUnitPlatform()
}
Run Code Online (Sandbox Code Playgroud)

useJUnitPlatform指示 Gradle 使用 Junit5 执行引擎。

  • 用于 JUnit5 测试的 Jupiter 引擎
  • 用于 JUnit4 测试的老式引擎

引擎必须存在于运行时类路径上才能进行测试。

特别是,以下配置无效:

// Invalid config
dependencies {
    testImplementation 'junit:junit:4.13.2'
}

test {
    useJUnitPlatform()
}
Run Code Online (Sandbox Code Playgroud)

您启用 JUnit5 引擎的使用,但不包含任何依赖项。这正是您的构建配置中发生的情况

这会导致异常,您可以在堆栈跟踪中看到:

Caused by: org.junit.platform.commons.PreconditionViolationException: Cannot create Launcher without at least one TestEngine; consider adding an engine implementation JAR to the classpath
    at org.junit.platform.commons.util.Preconditions.condition(Preconditions.java:296)
    at org.junit.platform.launcher.core.DefaultLauncher.<init>(DefaultLauncher.java:48)
    at org.junit.platform.launcher.core.LauncherFactory.create(LauncherFactory.java:105)
    at org.junit.platform.launcher.core.LauncherFactory.create(LauncherFactory.java:75)
    at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:97)
    at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:79)
    at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:75)
    at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:61)
Run Code Online (Sandbox Code Playgroud)

现在你有两个选择:

选项 1:仅使用 JUnit4

  • 消除useJUnitPlatform()
  • 仅使用 JUnit4 测试
dependencies {
    testImplementation 'junit:junit:4.13.2'
}
Run Code Online (Sandbox Code Playgroud)

选项 2:使用 JUnit5 平台和老式引擎

dependencies {
    testImplementation "junit:junit:4.13.2"
    testRuntimeOnly "org.junit.vintage:junit-vintage-engine:5.7.0"
}

test {
    useJUnitPlatform()
}
Run Code Online (Sandbox Code Playgroud)

从长远来看,请考虑:

  • 转向 JUnit5(如果您使用 Junit 平台并包含这两个引擎,则可以混合 Junit4 和 JUnit5 测试)。请参阅从 JUnit 4 迁移
  • 放弃 PowerMock - Mockito 拥有越来越多的功能,也许您可​​以放弃这种依赖。