Search code examples
springkotlinreactive-programmingjunit5reactor

JUnit dependency injection with Spring, MongoDB, and Kotlin


I am a Java developer who is dipping his toes into Spring and Spring WebFlux by writing a REST API. I typically do TDD and when trying to write some JUnit test cases to test MongoDB queries I am running into some issues.

Example Repository:

@Repository
interface XReactiveRepository: ReactiveMongoRepository<X, String>

The Java equivalent:

@Repository
public interface XReactiveRepository extends ReactiveMongoRepository<X, String> { }

In Java I can use @Autowired to inject this dependency into the Unit test like so:

@Autowired
private XReactiveRepository repository

However I cannot do that directly in Kotlin

@Autowired
private repository: XReactiveRepository

This results in a compilation issue stating that it must be initialized or declared abstract. I have tried dependency injection via constructor but that also does not work. Any Kotlin/Spring devs know how to properly inject a repository into a JUnit5 test?


Solution

  • What the compilation issue means is that your @Autowired fields should be lateinit var.

    However, Spring recommends using constructor injection over field injection.

    Constructor injection should also work if you are using @Autowired, i.e.

    class YourTestClass(@Autowired private val repository: XReactiveRepository)
    

    By default Spring does not autowire test class constructors, unless you use the @TestConstructor annotation or change the spring.test.constructor.autowire.mode system property to all.

    You can find this all from Spring Framework Reference.