0

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

Slaw
  • 37,820
  • 8
  • 53
  • 80
Pradeep
  • 3
  • 2

2 Answers2

0

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.

-1

For @ParameterizedTest in combination with @MethodSource you need to return a Stream of Arguments Stream<Arguments> from your method. Arguments is located in package package org.junit.jupiter.params.provider

For Example:

private static Stream<Arguments> validPurchasePlatformGenerator() {
    return Arrays.stream(PurchasePlatform.values())
        .filter(purchasePlatform -> !purchasePlatform.equals(PurchasePlatform.WEB))
        .map(Arguments::of);
}

and then

@ParameterizedTest
@DisplayName("Some DisplayText")
@MethodSource("validPurchasePlatformGenerator")
void purchaseValid_shouldReturnValidResult(PurchasePlatform purchasePlatform) { 
    // test code
}

If you want to use just plain string, you can also use @ValueSource instead of @MethodSource which would make more sense for your provided test.

For Example

@ParameterizedTest
@ValueSource(strings = { "a1", "a2" })
void testABC(String word) {
    System.out.println(word);
}
  • the example I quoted was an oversimplified demo of what I intent. I want to use `Arguments` of more complex Objects, but getting same error while trying that so cannot simply use `@ValueSource` – Pradeep Jun 22 '23 at 13:08
  • 2
    Using `Stream` is not _required_. It could be a `Stream` or `String[]`, since the test method has only a single `String` parameter. See [the documentation](https://junit.org/junit5/docs/current/api/org.junit.jupiter.params/org/junit/jupiter/params/provider/MethodSource.html). – Slaw Jun 22 '23 at 19:48