JUnit 5参数化测试-使用Kotlin在@MethodSource中“无法调用非静态方法”

问题描述 投票:0回答:1

期望

[将标准的JUnit 5测试转换为参数化测试,以便使用Kotlin中的@ParamterizedTest@MethodSource批注遍历一系列测试用例。

观察

@MethodSource无法访问数据流。这似乎特别是与该注释有关的问题,因为@ValueSource(strings = ["SF", "NYC"])会按预期遍历静态定义的选项。

错误:

PreconditionViolationException:无法在空目标上调用非静态方法{someMethodName}。

实施

参数化测试设置为传递数据类流,类似于Phillip Hauer在Data Classes for Parameterized Tests中概述的设置。

代码

build.gradle(:SomeProject)

dependencies {
    ...    
    classpath("de.mannodermaus.gradle.plugins:android-junit5:$junit5_version")
}

build.gradle(:someModule)

apply plugin: "de.mannodermaus.android-junit5"
android {
    ...
    compileOptions.targetCompatibility = JavaVersion.VERSION_1_8
    kotlinOptions.jvmTarget = "1.8"
}
dependencies {
    testImplementation "org.junit.jupiter:junit-jupiter-api:5.6.2"
    testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:5.6.2"
    testImplementation "org.junit.jupiter:junit-jupiter-params:5.6.2"
}

SomeTest.kt

class SomeTest {
    private val testDispatcher = TestCoroutineDispatcher()

    private fun someDataStates() = Stream.of(
        // Kotlin data class
        TestState("123"),
        TestState("345")
    )

    @ParameterizedTest
    @MethodSource("someDataStates")
    fun someTest(testState: TestState) = testDispatcher.runBlockingTest {
        // Test state here.
        ...
    }
}

构建环境

  • Android Studio 4.0
  • Build#AI-193.6911.18.40.6514223,建于2020年5月20日
  • 运行时版本:1.8.0_242-release-1644-b3-6222593 x86_64
  • VM:JetBrains s.r.o的OpenJDK 64位服务器VM
  • macOS 10.15.5
  • GC:ParNew,ConcurrentMarkSweep
  • 内存:1979M
  • [Cores:16
  • 注册表:ide.new.welcome.screen.force = true
  • 非捆绑插件:cn.wjdghd.unique.plugin.id,com.android.tool.sizereduction.plugin,com.developerphil.adbidea,com.thoughtworks.gauge,mobi.hsz.idea.gitignore

尝试的解决方案

1。将测试用例数据状态重构为顶级函数。

TestCases.kt

fun someDataStates() = Stream.of(
    TestState("123"),
    TestState("345")
)

SomeTest.kt

private fun SomeDataStates() = someDataStates()

@ParameterizedTest
@MethodSource("SomeDataStates")
fun someTest(testState: TestState) = testDispatcher.runBlockingTest {
   // Test state here.
   ...

}

2。将测试用例数据状态重构为List类型而不是Stream的顶级函数。

fun someDataStates() = listOf(
    TestState("123"),
    TestState("345")
)

完整错误日志

org.junit.platform.commons.PreconditionViolationException:无法在空目标上调用非静态方法[private final {someMethodName}。

在org.junit.platform.commons.util.Preconditions.condition(Preconditions.java:296) 在org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:682) 在org.junit.jupiter.params.provider.MethodArgumentsProvider.lambda $ provideArguments $ 1(MethodArgumentsProvider.java:46) 在java.util.stream.ReferencePipeline $ 3 $ 1.accept(ReferencePipeline.java:193) 在java.util.stream.ReferencePipeline $ 3 $ 1.accept(ReferencePipeline.java:193) 在java.util.Spliterators $ ArraySpliterator.forEachRemaining(Spliterators.java:948) 在java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482) 在java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472) 在java.util.stream.ForEachOps $ ForEachOp.evaluateSequential(ForEachOps.java:150) 在java.util.stream.ForEachOps $ ForEachOp $ OfRef.evaluateSequential(ForEachOps.java:173) 在java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) 在java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:485) 在java.util.stream.ReferencePipeline $ 7 $ 1.accept(ReferencePipeline.java:272) 在java.util.stream.ReferencePipeline $ 3 $ 1.accept(ReferencePipeline.java:193) 在java.util.stream.ReferencePipeline $ 3 $ 1.accept(ReferencePipeline.java:193) 在java.util.stream.ReferencePipeline $ 3 $ 1.accept(ReferencePipeline.java:193) 在java.util.ArrayList $ ArrayListSpliterator.forEachRemaining(ArrayList.java:1382) 在java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482) 在java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472) 在java.util.stream.ForEachOps $ ForEachOp.evaluateSequential(ForEachOps.java:150) 在java.util.stream.ForEachOps $ ForEachOp $ OfRef.evaluateSequential(ForEachOps.java:173) 在java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) 在java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:485) 在java.util.stream.ReferencePipeline $ 7 $ 1.accept(ReferencePipeline.java:272) 在java.util.ArrayList $ ArrayListSpliterator.forEachRemaining(ArrayList.java:1382) 在java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482) 在java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472) 在java.util.stream.ForEachOps $ ForEachOp.evaluateSequential(ForEachOps.java:150) 在java.util.stream.ForEachOps $ ForEachOp $ OfRef.evaluateSequential(ForEachOps.java:173) 在java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) 在java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:485) 在org.junit.jupiter.engine.descriptor.TestTemplateTestDescriptor.execute(TestTemplateTestDescriptor.java:106) 在org.junit.jupiter.engine.descriptor.TestTemplateTestDescriptor.execute(TestTemplateTestDescriptor.java:41) 在org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda $ executeRecursively $ 5(NodeTestTask.java:135) 在org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)处 在org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda $ executeRecursively $ 7(NodeTestTask.java:125) 在org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135) 在org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda $ executeRecursively $ 8(NodeTestTask.java:123) 在org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)处 在org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122) 在org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80) 在java.util.ArrayList.forEach(ArrayList.java:1257) 在org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38) 在org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda $ executeRecursively $ 5(NodeTestTask.java:139) 在org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)处 在org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda $ executeRecursively $ 7(NodeTestTask.java:125) 在org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135) 在org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda $ executeRecursively $ 8(NodeTestTask.java:123) 在org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)处 在org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122) 在org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80) 在java.util.ArrayList.forEach(ArrayList.java:1257) 在org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38) 在org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda $ executeRecursively $ 5(NodeTestTask.java:139) 在org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)处 在org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda $ executeRecursively $ 7(NodeTestTask.java:125) 在org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135) 在org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda $ executeRecursively $ 8(NodeTestTask.java:123) 在org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)处 在org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122) 在org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80) 在org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32) 在org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57) 在org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51) 在org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:248) 在org.junit.platform.launcher.core.DefaultLauncher.lambda $ execute $ 5(DefaultLauncher.java:211) 在org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:226) 在org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:199) 在org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:132) 在com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:69) 在com.intellij.rt.junit.IdeaTestRunner $ Repeater.startRunnerWithArgs(IdeaTestRunner.java:33) 在com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230) 在com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58) 禁止:org.junit.platform.commons.PreconditionViolationException:配置错误:您必须为此@ParameterizedTest配置至少一组参数 在org.junit.platform.commons.util.Preconditions.condition(Preconditions.java:281) 在org.junit.jupiter.params.ParameterizedTestExtension.lambda $ provideTestTemplateInvocationContexts $ 6(ParameterizedTestExtension.java:90) 在java.util.stream.AbstractPipeline.close(AbstractPipeline.java:323) 在java.util.stream.ReferencePipeline $ 7 $ 1.accept(ReferencePipeline.java:279) ... 49更多

处理完成,退出代码为255

android kotlin junit android-testing junit5
1个回答
0
投票

我想您正在丢失信息,告诉JUnit一次实例化您的测试类,如下所示:

import org.junit.jupiter.api.TestInstance
import org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS

@TestInstance(PER_CLASS) // <--- This one will do the trick
class SomeTest {

    private val testDispatcher = TestCoroutineDispatcher()

    @ParameterizedTest
    @MethodSource("someDataStates")
    fun someTest(testState: TestState) = testDispatcher.runBlockingTest {
        // Test state here.
        ...
    }

    private fun someDataStates() = listOf(
        TestState("123"),
        TestState("345")
    )
}
© www.soinside.com 2019 - 2024. All rights reserved.