Search code examples
javatestingjunit5

Not able to use @MethodSource in @ParameterizedTest


I am trying to create a parameterised test with a method source. Following is the code :

import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;

class ABCTest {

    @ParameterizedTest
    @MethodSource("abc")
    void testABC(String word) {
        System.out.println(word);
    }

    static Stream<String> abc() {
        return Stream.of("a1",
                "b2");
    }

}

But this doesn't work; while trying to run the test case, I am

java.lang.NoSuchMethodError: 'java.lang.String[] org.junit.platform.commons.util.ReflectionUtils.parseQualifiedMethodName(java.lang.String)'
.
.
.
    Suppressed: org.junit.platform.commons.PreconditionViolationException: Configuration error: You must configure at least one set of arguments for this @ParameterizedTest
        at org.junit.platform.commons.util.Preconditions.condition(Preconditions.java:281)
        at org.junit.jupiter.params.ParameterizedTestExtension.lambda$provideTestTemplateInvocationContexts$5(ParameterizedTestExtension.java:98)

Following is my pom.xml :

<?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><hiding_this_intentionally></groupId>
    <artifactId><hiding_this_intentionally></artifactId>
    <packaging>pom</packaging>
    <version>4.3.20-SNAPSHOT</version>
    <modules>
        <module><hiding_this_intentionally></module>
        <module><hiding_this_intentionally></module>
    </modules>

    <parent>
        <groupId><hiding_this_intentionally></groupId>
        <artifactId><hiding_this_intentionally></artifactId>
        <version>1.0.19</version>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!--        Java related properties -->
        <jdk.source.version>17</jdk.source.version>
        <jdk.target.version>17</jdk.target.version>
        <jdk.release.version>17</jdk.release.version>
<!--        Maven related properties -->
        <maven.compiler.plugin.version>3.9.0</maven.compiler.plugin.version>
        <maven.deploy.plugin.version>2.8.2</maven.deploy.plugin.version>
        <maven.shade.plugin.version>3.3.0</maven.shade.plugin.version>
        <maven.javadoc.skip>true</maven.javadoc.skip>

        <userservice-model.version>2.0.8</userservice-model.version>
        <vault-model.version>0.0.66</vault-model.version>
        <ablaze.version>3.0.15</ablaze.version>

        <aspectj.maven.plugin.version>1.13.1</aspectj.maven.plugin.version>

        <json-rules.version>1.0.11</json-rules.version>
        <zjsonpatch.version>0.4.3</zjsonpatch.version>
        <lombok.version>1.18.22</lombok.version>
        <lombok.maven.version>1.18.20.0</lombok.maven.version>
        <junit.version>4.12</junit.version>
        <guava.version>30.1.1-jre</guava.version>
        <h2.version>1.4.191</h2.version>
        <!-- Sonar-JaCoCo properties -->
        <sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
        <sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
        <sonar.jacoco.reportPaths>${project.basedir}/../target/jacoco.exec</sonar.jacoco.reportPaths>
        <sonar.language>java</sonar.language>
        <sonar.buildbreaker.skip>true</sonar.buildbreaker.skip>
        <giftcard.provider.model.version>1.0.3</giftcard.provider.model.version>
        <log4j.to.slf4j.version>2.8.2</log4j.to.slf4j.version>
        <jersey.guava.version>2.6</jersey.guava.version>
        <clearspring.analytics.stream.version>2.9.5</clearspring.analytics.stream.version>
        <sonar.qualitygate.wait>false</sonar.qualitygate.wait>

        <gpp.aerospike.version>4.1.8</gpp.aerospike.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.flipkart.ranger</groupId>
                <artifactId>ranger</artifactId>
                <version>0.6.3</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.apache.hbase</groupId>
            <artifactId>hbase-shaded-client</artifactId>
            <version>2.0.1</version>
        </dependency>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>${guava.version}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.module</groupId>
            <artifactId>jackson-module-afterburner</artifactId>
        </dependency>
        <dependency>
            <groupId>io.raven.dropwizard</groupId>
            <artifactId>dropwizard-jmxmp</artifactId>
        </dependency>

        <dependency>
            <groupId>com.raskasa.metrics</groupId>
            <artifactId>metrics-okhttp</artifactId>
        </dependency>
        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
        </dependency>
        <dependency>
            <groupId>com.clearspring.analytics</groupId>
            <artifactId>stream</artifactId>
            <version>${clearspring.analytics.stream.version}</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
        </dependency>
        <dependency>
            <groupId>io.appform.rules</groupId>
            <artifactId>json-rules</artifactId>
            <version>${json-rules.version}</version>
        </dependency>
        <dependency>
            <groupId>com.flipkart.zjsonpatch</groupId>
            <artifactId>zjsonpatch</artifactId>
            <version>${zjsonpatch.version}</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>io.dropwizard</groupId>
            <artifactId>dropwizard-jackson</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>ch.qos.logback</groupId>
                    <artifactId>logback-classic</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-to-slf4j</artifactId>
            <version>${log4j.to.slf4j.version}</version>
        </dependency>

        <dependency>
            <groupId>org.glassfish.jersey.bundles.repackaged</groupId>
            <artifactId>jersey-guava</artifactId>
            <version>${jersey.guava.version}</version>
        </dependency>
        <dependency>
            <groupId>javax.activation</groupId>
            <artifactId>activation</artifactId>
        </dependency>
        <dependency>
            <groupId>org.reflections</groupId>
            <artifactId>reflections</artifactId>
        </dependency>

        <!-- Testing -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-params</artifactId>
            <version>5.9.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>${h2.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.dropwizard</groupId>
            <artifactId>dropwizard-testing</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.javassist</groupId>
            <artifactId>javassist</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-deploy-plugin</artifactId>
                <version>${maven.deploy.plugin.version}</version>
                <configuration>
                    <skip>false</skip>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>delombok</goal>
                        </goals>
                    </execution>
                </executions>
                <version>${lombok.maven.version}</version>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${maven.compiler.plugin.version}</version>
                <configuration>
                    <source>${jdk.source.version}</source>
                    <target>${jdk.target.version}</target>
                    <release>${jdk.release.version}</release>
                    <showWarnings>true</showWarnings>
                    <debug>false</debug>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <profiles>
        <profile>
            <id>docker</id>
        </profile>
    </profiles>
</project>

Can someone help me here?

Tried changing the version of junit-jupiter-params as suggested in NoSuchMethodError: org.junit.platform.commons.util.ReflectionUtils.tryToLoadClass, still didn't work


Solution

  • As mentioned by @johanneslink, you have a lib version mismatch. You are using JUnit4 framework (specifically JUnit 4.12), while @ParameterizedTest annotation (as well as junit-jupiter-params dependency in your pom.xml) belongs to Junit5 framework.

    To include JUnit5 into your project, remove the JUnit4 dependency and add the following to your pom.xml:

    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-engine</artifactId>
        <version>5.10.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-api</artifactId>
        <version>5.10.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-params</artifactId>
        <version>5.10.0</version>
        <scope>test</scope>
    </dependency>

    Here is the guide for setting up JUnit5

    Note that it is important to maintain the same versions of dependecies even when you are using JUnit5. For example, including junit-jupiter-engine 5.10.0 with junit-jupiter-params 5.9.2 will result in non-working code.

    Additionaly, there is a JUnit5 Aggregator, which is a shorthand for including three dependencies listed above, using it will make your pom less cluttered and leave out burden of checking that the versions of all three dependencies are the same.

    <dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <version>5.10.0</version>
    <scope>test</scope>
    

    Also note that there is a way to create parameterized tests with JUnit4 (see here), but I recommend to upgrade to JUnit5 anyway, because it is a more capable and easier to use framework overall.