SpringBoot does not run unit tests when added into dependencyManagement

Tags: , , , ,



My project is supposed to be inherited from a custom parent and at the same time use Spring Boot. The standard solution for that is using <dependencyManagement> section as described here.

The problem is when a Spring Boot dependency is added into the section, maven does not see any unit tests (Test runs = 0). I reproduced that with artifacts spring-boot-dependencies and spring-boot-starter.

Steps to reproduce:

  1. create a maven project with one unit test SampleTest and the following pom.
  2. run mvn test.
  3. see that SampleTest has run and failed
  4. uncomment the block in <dependencyManagement> to import Spring Boot
  5. run mvn test
  6. see no tests have run and the build is succesfull.

I had similar problems with older versions of surefire, which could not find JUnit5 tests in a similar manner. But the effective pom shows that in this case plugins’ versions are correctly set to 3.0.0-M4 and not overridden by SpringBoot.

Could you help me fix the problem with running tests and properly apply Spring Boot in this case?


src/test/java/org/example/SampleTest.java

package org.example;

import org.junit.jupiter.api.*;

class SampleTest{
    @Test
    void test(){
        Assertions.assertEquals(0, 1);
    }
}

pom.xml

The following sample does not have a parent: I’ve just copied plugins and dependencies from that to keep it concise.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>spring-boot-import</artifactId>
    <version>1.0</version>

    <dependencyManagement>
    <!-- when this block is uncommented no unit tests are found in the project-->

    <!--
        <dependencies>
          <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.2.5.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
          </dependency>
        </dependencies>
    -->
    </dependencyManagement>

    <properties>
        <version.java>11</version.java>
        <version.junit.jupiter>5.6.0</version.junit.jupiter>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <compilerVersion>${version.java}</compilerVersion>
                    <release>${version.java}</release>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.0.0-M4</version>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>3.0.0-M4</version>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>${version.junit.jupiter}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

Answer

Including the spring-boot-dependencies dependencies changes the transitive dependencies of the junit-jupiter-engine dependency.

The output of mvn dependency:tree will show this.

Before

[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ spring-boot-import ---
[INFO] org.example:spring-boot-import:jar:1.0
[INFO] - org.junit.jupiter:junit-jupiter-engine:jar:5.6.0:test
[INFO]    +- org.apiguardian:apiguardian-api:jar:1.1.0:test
[INFO]    +- org.junit.platform:junit-platform-engine:jar:1.6.0:test
[INFO]    |  +- org.opentest4j:opentest4j:jar:1.2.0:test
[INFO]    |  - org.junit.platform:junit-platform-commons:jar:1.6.0:test
[INFO]    - org.junit.jupiter:junit-jupiter-api:jar:5.6.0:test

After

[INFO] org.example:spring-boot-import:jar:1.0
[INFO] - org.junit.jupiter:junit-jupiter-engine:jar:5.6.0:test
[INFO]    +- org.apiguardian:apiguardian-api:jar:1.1.0:test
[INFO]    +- org.junit.platform:junit-platform-engine:jar:1.5.2:test
[INFO]    |  +- org.opentest4j:opentest4j:jar:1.2.0:test
[INFO]    |  - org.junit.platform:junit-platform-commons:jar:1.5.2:test
[INFO]    - org.junit.jupiter:junit-jupiter-api:jar:5.5.2:test

As you can see the junit-platform-engine and friends changed from 1.6.0 to 1.5.2 and the API from 5.6.0 to 5.5.2. As those jars are incompatible versions your tests won’t run anymore.

To fix you can do 1 of the following

  1. Add all additional, transitive, dependencies with an explicit version
  2. Add the junit-bom as well to the dependencyManagement section before the Spring Boot one, to force the versions
  3. Downgrade to JUnit 5.5.2 to align with the Spring Boot managed version


Source: stackoverflow