How to inject a Spring bean in a JUnit 5 test class written in Kotlin?

Viewed 3721

I try to test something in a Kotlin project using JUnit 5 and Spring Boot, but I'm unable to inject a bean in my test class.

I tried many different annotations, but the injection nerver worked...

Here's my test class:

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@SpringBootTest
@ExtendWith(SpringExtension::class)
class FooTest {

   @Autowired
   lateinit var repo: BarRepository

   @BeforeAll
   fun setup() {
   }

   @Test
   fun testToto() {
   }
}

With this annotations combination, the code raises the following exception: java.lang.NoClassDefFoundError:org/springframework/boot/context/properties/source/ConfigurationPropertySource. And I'm actually unable to find where does this exception come from... I tried to do some research about this exception, but I didn't find anything satisfying...

2 Answers

I finally found how to fix my problem. My Spring Boot version was initially "1.5.3", so I changed it my pom.xml to the "2.0.2" version. Now my tests run fine and my bean is correctly injected as expected. Here's the modified part of my pom.xml:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.2.RELEASE</version>
    <relativePath/>
</parent>

Everything is fine after modifying the version. Here are the usefull dependencies to test with Junit:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    <exclusions>
        <exclusion>
            <artifactId>junit</artifactId>
            <groupId>junit</groupId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-api</artifactId>
    <version>5.3.2</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <scope>test</scope>
</dependency>

I guess you have an error in your dependencies. If you generate a new Spring Boot Kotlin project from https://start.spring.io/#!language=kotlin then customize your dependencies as following, it will work as expected:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.jetbrains.kotlin</groupId>
        <artifactId>kotlin-reflect</artifactId>
    </dependency>
    <dependency>
        <groupId>org.jetbrains.kotlin</groupId>
        <artifactId>kotlin-stdlib-jdk8</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <artifactId>junit</artifactId>
                <groupId>junit</groupId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-api</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-engine</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

Please also notice that you don't need to specify @ExtendWith(SpringExtension::class) since @SpringBootTest is already meta annotated with this annotation as of Spring Boot 2.1.

Related