JUnit 5 Collection type parameters cause errors with “@ParameterizedTest”

徘徊边缘 提交于 2019-12-24 07:45:35

问题


I cannot find the reason of the errors from previously asked questions, because they were about "@Test" (which does not allow custom data types).

I have a program which takes a String type input (which is usually a block of text), and returns input's sentences in the form of List. To test this program properly I tried to store my inputs and expected outputs (which will be compared to the outputs of my program, purpose of the test) in the form of List. Here DataStructure class consists of 2 attributes: a String type attribute, and a List type attribute.

In total, I have some necessary classes about the program itself, SentenceSplitterTest class, DataStructure class, and Collection class. In Collection class I handle the loading process of the List mentioned above. I basically do some file operations and store my inputs and expected outputs inside Collection class. Below here is the content of my ProgramTest.java file.

package Classes;

import org.junit.Before;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;

@RunWith(Parameterized.class)
public class SentenceSplitterTest  {

    private String input;
    private List<String> output = new ArrayList<>();
    private SentenceSplitter sentencesplitter;
    private static CollectionClass collectionClass;

    static {
        try {
            collectionClass = new CollectionClass();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public SentenceSplitterTest(String input, List<String> output)  {
        super();
        this.input = input;
        this.output = output;
    }

    @Before
    public void initialize() throws IOException {

        sentencesplitter = new SentenceSplitter();
    }

    @ParameterizedTest
    @MethodSource("data")
    public void testSentenceSplitterTest() {

        System.out.println("Expected output: " + output);
        assertEquals(output, sentencesplitter.sentenceSplit(input));
    }

    public static Collection data() {
        return collectionClass.getContent();
    }
}

As you can see, I used @MethodSource("data") to set my parameters. My test screen looks like this

I get the following error for InitializationError in the screenshot:

java.lang.Exception: No public static parameters method on class Classes.SentenceSplitterTest

I get the following error for each element in the screenshot:

org.junit.jupiter.api.extension.ParameterResolutionException: No ParameterResolver registered for parameter [java.lang.String arg0] in executable [public Classes.SentenceSplitterTest(java.lang.String,java.util.List)]. I cannot find what I should do to solve the issues. Please help.

EDIT 1: I am asked to share CollectionClass class.

package Classes;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

import static java.nio.file.Files.readAllLines;

public class CollectionClass {

    private static List<DataStructure> collection = new ArrayList<>();

    public List<DataStructure> getContent() {
        return collection;
    }

    public CollectionClass() throws IOException {

        List<String> inputs = readAllLines(Paths.get("inputs.txt"), StandardCharsets.UTF_8);
        List<String> outputs = readAllLines(Paths.get("outputs.txt"), StandardCharsets.UTF_8);

        int i = 0;
        int j = 0;
        int ctr = 0;

        while(i< inputs.size() || j< outputs.size()) {

            DataStructure structure = new DataStructure();
            String inputIncoming = null;
            List<String> outputIncoming = new ArrayList<String>();

            if(i< inputs.size()) {

                if(!inputs.get(i).equals("-")) {
                    // nothing

                }
                else {
                    i++;
                    inputIncoming = inputs.get(i);
                   structure.string = inputIncoming;
                }
            }

            if(j< outputs.size()) {


                if(!outputs.get(j).equals("-") && !outputs.get(j).equals("--")) {
                    // nothing
                }
                else {
                    if(outputs.get(j).equals("-")) {
                        j++;
                        outputIncoming.add(outputs.get(j));
                        structure.listOfString = outputIncoming;
                    }
                    else if(outputs.get(j).equals("--")) {
                        j++;
                        outputIncoming.add(outputs.get(j));
                        j++;
                        outputIncoming.add(outputs.get(j));
                        structure.listOfString = outputIncoming;
                    }
                }
            }

            collection.add(ctr,structure);

            i++;
            j++;
            ctr++;
        }
        for(DataStructure structure: collection) {
            System.out.println(structure.string);
            System.out.println(structure.listOfString);
        }
    }
}

I want to add DataStructure class, too.

package Classes;

import java.util.ArrayList;
import java.util.List;

public class DataStructure {

    public String string;
    public List<String> listOfString = new ArrayList<>();
}

EDIT 2: I am asked to put stacktrace. Here it is.

java.lang.NullPointerException
    at Classes.SentenceSplitterTest.testSentenceSplitterTest(SentenceSplitterTest.java:46)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:389)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:115)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:167)
    at org.junit.jupiter.engine.execution.ThrowableCollector.execute(ThrowableCollector.java:40)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:163)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:110)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:57)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.lambda$execute$3(HierarchicalTestExecutor.java:83)
    at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:77)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.lambda$null$0(HierarchicalTestExecutor.java:85)
    at org.junit.jupiter.engine.descriptor.TestTemplateTestDescriptor.execute(TestTemplateTestDescriptor.java:114)
    at org.junit.jupiter.engine.descriptor.TestTemplateTestDescriptor.lambda$execute$2(TestTemplateTestDescriptor.java:86)
    at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
    at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
    at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
    at java.base/java.util.stream.ReferencePipeline$11$1.accept(ReferencePipeline.java:442)
    at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
    at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
    at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
    at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
    at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
    at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1492)
    at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:658)
    at java.base/java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:274)
    at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
    at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
    at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
    at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
    at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
    at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:497)
    at java.base/java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:274)
    at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
    at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
    at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
    at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1492)
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
    at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
    at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
    at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:497)
    at java.base/java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:274)
    at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1492)
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
    at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
    at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
    at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:497)
    at org.junit.jupiter.engine.descriptor.TestTemplateTestDescriptor.execute(TestTemplateTestDescriptor.java:86)
    at org.junit.jupiter.engine.descriptor.TestTemplateTestDescriptor.execute(TestTemplateTestDescriptor.java:36)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.lambda$execute$3(HierarchicalTestExecutor.java:83)
    at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:77)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.lambda$null$2(HierarchicalTestExecutor.java:92)
    at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
    at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:177)
    at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133)
    at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
    at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
    at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
    at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:497)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.lambda$execute$3(HierarchicalTestExecutor.java:92)
    at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:77)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.lambda$null$2(HierarchicalTestExecutor.java:92)
    at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
    at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:177)
    at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133)
    at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
    at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
    at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
    at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:497)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.lambda$execute$3(HierarchicalTestExecutor.java:92)
    at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:77)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:51)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:43)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:170)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:154)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:90)
    at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:74)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

回答1:


You're mixing JUnit 4 and JUnit Jupiter parameterized tests. In JUnit JUpiter, there's no test runner, the constructor remains parameterless and you pass the parameters to the test method (in a way that's a bit reminiscent of JUnit 4's Theories):

public class SentenceSplitterTest  {
    private SentenceSplitter sentencesplitter;
    private static CollectionClass collectionClass;

    // Initialization of CollectionClass moved here (instead of a static block) for two 
    // reasons:
    // 1. If the initialization fails, you can't run the test anyway - better fail 
    //    right here that print an error and continue to the test which we 
    //    know won't work
    // 2. It just looks neater
    @BeforeAll
    public static void initializeCollectionClass() throws IOException {
        collectionClass = new CollectionClass();
    }

    @BeforeEach
    public void initializeSentenceSplitter() throws IOException {
        sentencesplitter = new SentenceSplitter();
    }

    @ParameterizedTest
    @MethodSource("data")
    public void testSentenceSplitterTest(DataStructure ds) {
        String input = ds.string;
        List<String> output = ds.listOfString;
        assertEquals(output, sentencesplitter.sentenceSplit(input));
    }

    public static Stream<DataStructure> data() {
        return collectionClass.getContent().stream();
    }
}


来源:https://stackoverflow.com/questions/51319784/junit-5-collection-type-parameters-cause-errors-with-parameterizedtest

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!