Hello!
I am using Spring Boot 4.0.0-RC1 + JUnit 6 + Kotlin 2.2.21 + Gradle 8.14.3
I created a simple class that generates a positive integer:
@Service
class RandomService {
suspend fun getRandomPositiveInt(): Int {
delay(1_000)
return Random.nextInt(from = 1, until = Int.MAX_VALUE)
}
}
Then I created a test for the RandomService class:
@SpringBootTest
class RandomServiceTest1(
@Autowired private val randomService: RandomService,
) {
@Test
suspend fun `check getRandomPositiveInt`() {
val result = randomService.getRandomPositiveInt()
assertTrue { result > 0 }
}
}
And when I try to run the test, the following problem occurs:
Click to see a full error
org.junit.platform.launcher.core.DiscoveryIssueException: TestEngine with ID 'junit-jupiter' encountered a critical issue during test discovery:
(1) [ERROR] ClassSelector [className = 'io.sultazat.demo.service.RandomServiceTest1', classLoader = jdk.internal.loader.ClassLoaders$AppClassLoader@2c854dc5] resolution failed
Source: ClassSource [className = 'io.sultazat.demo.service.RandomServiceTest1', filePosition = null]
at io.sultazat.demo.service.RandomServiceTest1.<no-method>(SourceFile:0)
Cause: org.junit.platform.commons.PreconditionViolationException: Failed to get Kotlin function for method: static java.lang.Object io.sultazat.demo.service.RandomServiceTest1.check getRandomPositiveInt$suspendImpl(io.sultazat.demo.service.RandomServiceTest1,kotlin.coroutines.Continuation)
at org.junit.platform.commons.util.Preconditions.condition(Preconditions.java:339)
at org.junit.platform.commons.util.Preconditions.notNull(Preconditions.java:74)
at org.junit.platform.commons.util.KotlinSuspendingFunctionUtils.getKotlinFunction(KotlinSuspendingFunctionUtils.java:112)
at org.junit.platform.commons.util.KotlinSuspendingFunctionUtils.getReturnType(KotlinSuspendingFunctionUtils.java:43)
at org.junit.platform.commons.util.KotlinReflectionUtils.getKotlinSuspendingFunctionReturnType(KotlinReflectionUtils.java:127)
at org.junit.jupiter.engine.support.MethodReflectionUtils.getReturnType(MethodReflectionUtils.java:31)
at org.junit.jupiter.engine.discovery.predicates.IsTestableMethod.lambda$hasVoidReturnType$0(IsTestableMethod.java:68)
at org.junit.platform.engine.support.discovery.DiscoveryIssueReporter.lambda$createReportingCondition$0(DiscoveryIssueReporter.java:121)
at org.junit.platform.engine.support.discovery.DiscoveryIssueReporter$Condition.lambda$and$0(DiscoveryIssueReporter.java:171)
at org.junit.jupiter.engine.discovery.predicates.IsTestableMethod.test(IsTestableMethod.java:49)
at org.junit.jupiter.engine.discovery.predicates.IsTestMethod.test(IsTestMethod.java:24)
at org.junit.jupiter.engine.discovery.predicates.IsTestableMethod.test(IsTestableMethod.java:32)
at java.base/java.util.function.Predicate.lambda$or$2(Predicate.java:101)
at java.base/java.util.function.Predicate.lambda$or$2(Predicate.java:101)
at org.junit.platform.commons.util.ReflectionUtils.findMethod(ReflectionUtils.java:1513)
at org.junit.platform.commons.util.ReflectionUtils.isMethodPresent(ReflectionUtils.java:1379)
at org.junit.jupiter.engine.discovery.predicates.TestClassPredicates.hasTestOrTestFactoryOrTestTemplateMethods(TestClassPredicates.java:107)
at org.junit.jupiter.engine.discovery.predicates.TestClassPredicates.looksLikeIntendedTestClass(TestClassPredicates.java:82)
at org.junit.jupiter.engine.discovery.predicates.TestClassPredicates.looksLikeIntendedTestClass(TestClassPredicates.java:76)
at org.junit.jupiter.engine.discovery.ClassSelectorResolver.isAcceptedStandaloneTestClass(ClassSelectorResolver.java:114)
at org.junit.jupiter.engine.discovery.ClassSelectorResolver.resolveStandaloneTestClass(ClassSelectorResolver.java:105)
at org.junit.jupiter.engine.discovery.ClassSelectorResolver.resolve(ClassSelectorResolver.java:101)
at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.lambda$resolve$0(EngineDiscoveryRequestResolution.java:137)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
at java.base/java.util.ArrayList$ArrayListSpliterator.tryAdvance(ArrayList.java:1685)
at java.base/java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:129)
at java.base/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:527)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:513)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
at java.base/java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:150)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:647)
at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolve(EngineDiscoveryRequestResolution.java:191)
at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolve(EngineDiscoveryRequestResolution.java:128)
at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolveCompletely(EngineDiscoveryRequestResolution.java:94)
at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.run(EngineDiscoveryRequestResolution.java:85)
at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolver.resolve(EngineDiscoveryRequestResolver.java:150)
at org.junit.jupiter.engine.discovery.DiscoverySelectorResolver.resolveSelectors(DiscoverySelectorResolver.java:62)
at org.junit.jupiter.engine.JupiterTestEngine.discover(JupiterTestEngine.java:74)
at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discoverEngineRoot(EngineDiscoveryOrchestrator.java:195)
at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discoverSafely(EngineDiscoveryOrchestrator.java:174)
at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discover(EngineDiscoveryOrchestrator.java:119)
at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discover(EngineDiscoveryOrchestrator.java:84)
at org.junit.platform.launcher.core.DefaultLauncher.discover(DefaultLauncher.java:119)
at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$1(DefaultLauncher.java:112)
at java.base/java.util.Optional.orElseGet(Optional.java:364)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:109)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:93)
at org.junit.platform.launcher.core.DelegatingLauncher.execute(DelegatingLauncher.java:48)
at org.junit.platform.launcher.core.InterceptingLauncher.lambda$execute$0(InterceptingLauncher.java:41)
at org.junit.platform.launcher.core.ClasspathAlignmentCheckingLauncherInterceptor.intercept(ClasspathAlignmentCheckingLauncherInterceptor.java:25)
at org.junit.platform.launcher.core.InterceptingLauncher.execute(InterceptingLauncher.java:40)
at org.junit.platform.launcher.core.DelegatingLauncher.execute(DelegatingLauncher.java:48)
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:124)
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:99)
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:94)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:63)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
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:92)
at jdk.proxy1/jdk.proxy1.$Proxy4.stop(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:200)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:132)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:103)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:63)
at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:122)
at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:72)
at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)
If I change a name of the test, it works:
@Test
suspend fun `check int`() {
val result = randomService.getRandomPositiveInt()
assertTrue { result > 0 }
}
Some extra examples that work:
- suspend fun `check check`()
- suspend fun check_check()
- suspend fun `check again`()
- suspend fun `check 1`()
- suspend fun `test int`()
- suspend fun `test getRandomPositiveInt`()
- suspend fun `check check check 1`()
- suspend fun `check check check 20000000`()
- suspend fun `trying super long test name hello how are you int`()
Some extra examples that do not work:
- suspend fun `check getRandomPositiveInt`()
- suspend fun `check check check`()
- suspend fun `trying super long test name hello how are you`()
- suspend fun `check generator`()
- suspend fun check_getRandomPositiveInt()
- suspend fun check_check_check()
If I create unit tests for RandomService, then I don't have the issue anymore:
class RandomServiceTest2 {
private val randomService = RandomService()
@Test
suspend fun `check int`() {
val result = randomService.getRandomPositiveInt()
assertTrue { result > 0 }
}
@Test
suspend fun `check getRandomPositiveInt`() {
val result = randomService.getRandomPositiveInt()
assertTrue { result > 0 }
}
}
I created a small demo project with a source code: https://github.com/sultazat/junit6-kotlin-issue