micronaut-projects / micronaut-core

Micronaut Application Framework
http://micronaut.io
Apache License 2.0
6.09k stars 1.07k forks source link

Regression Kotest StringSpec not working with Picocli and Micronaut 3.6.x #8001

Open Xaseron opened 2 years ago

Xaseron commented 2 years ago

Expected Behavior

Simple StringSpec should work:

class DemoCommandStringTest : StringSpec() {
    init {
        val ctx = ApplicationContext.run(Environment.CLI, Environment.TEST)
        "Hi!" {

            val baos = ByteArrayOutputStream()
            System.setOut(PrintStream(baos))

            val args = arrayOf("-v")
            PicocliRunner.run(DemoCommand::class.java, ctx, *args)

            baos.toString() shouldContain "Hi!"
        }

        ctx.close()
    }
}

Actual Behaviour

picocli.CommandLine$InitializationException: Could not instantiate class com.example.DemoCommand: io.micronaut.context.exceptions.BeanInstantiationException: Error instantiating bean of type  [com.example.GoogleRepo]

Message: Multiple possible bean candidates found: [io.micronaut.aop.InterceptorRegistry, io.micronaut.aop.InterceptorRegistry]
Path Taken: new DemoCommand() --> DemoCommand.googleRepo --> new GoogleRepo([GoogleDe googleDe],GoogleCom googleCom)

Steps To Reproduce

  1. Have two Micronaut Http Clients that inherit the same interface
  2. Have a Singleton that inject both clients
  3. Inject that Singleton into a Picocli Command
  4. Write a Kotest StringSpec test

My test worked with Micronaut 3.5.5. But after updating to Micronaut 3.6.3 StringSpec tests with above described setup are failing. The strange thing is that other test variants like Behavior Specs are not affected. StringSpec: https://github.com/Xaseron/bugreport/blob/master/src/test/kotlin/com/example/DemoCommandStringTest.kt DescribeSpec: https://github.com/Xaseron/bugreport/blob/master/src/test/kotlin/com/example/DemoCommandBehaviorTest.kt

Both test do exactly the same but StringSpec is not working anymore with Micronaut 3.6.x

Environment Information

JDK: 17 Micronaut: 3.6.0 and newer

Example Application

https://github.com/Xaseron/bugreport

Version

3.6.3

Xaseron commented 2 years ago

I have found the cause, but i don't really understand it. The tests are only working when the ApplicationContext is defined inside the TestContext.

Working test:

class DemoCommandStringTest : StringSpec() {
    init {
        "Hi!" {
            val ctx = ApplicationContext.run(Environment.CLI, Environment.TEST)
            val baos = ByteArrayOutputStream()
            System.setOut(PrintStream(baos))

            val args = arrayOf("-v")
            PicocliRunner.run(DemoCommand::class.java, ctx, *args)

            baos.toString() shouldContain "Hi!"

            ctx.close()
        }
    }
}