micronaut-projects / micronaut-test

Repository for Test Related Utilities for Micronaut
Apache License 2.0
82 stars 61 forks source link

@MicronautTest annotation on super class #370

Closed andreygfranca closed 3 years ago

andreygfranca commented 3 years ago

I'm trying to create some integration tests on my project, and I have not just to insert some records on the database, but also get some container ports running with testcontainers lib (because ports are random when the application starts) before the test run. Usually, on spring projects I've been creating superclasses that do this kind of task (populating database, get random ports on runtime, etc.)

When using @MicronautTest annotation on a superclass and then inheriting this class on a concrete test class, beans are not being injected.

Task List

Steps to Reproduce

  1. Create a singleton bean (FooService)
  2. Create a super class ITSpecification that extends Specification (from spock framework)
  3. Create a concrete test class that extends ITSpecification, lets say FooServiceSpec
  4. Inject FooService, then fails
@Singleton
class FooService {
    String greet() {
        return "hello"
    }
}
@MicronautTest
abstract class ITSpecification extends Specification {
    // populate database, get container's ports
}
class FooServiceSpec extends ITSpecification {
    @Inject
    FooService fooService

    def "should return hello"() {
        expect:
        fooService.greet() == "hello"
    }
}

Error:

fooService.greet() == "hello"
|          |
null       java.lang.NullPointerException: Cannot invoke method greet() on null object
            at com.example.FooServiceSpec.should return hello(FooServiceSpec.groovy:13)

Expected Behaviour

Should allow injecting the beans into the base class because the superclass has the @MicronautTest annotation

Actual Behaviour

It is not allowing to inject beans into the base class

Environment Information

nmuzhichin commented 3 years ago

Hello. Using @Shared annotation solves the problem.

import spock.lang.Shared

class FooServiceSpec extends ITSpecification {
    @Inject @Shared
    FooService fooService

    def "should return hello"() {
        expect:
        fooService.greet() == "hello"
    }
}
jameskleeh commented 3 years ago

Currently its designed so that @MicronautTest must exist on each test class