параметризованный тестовый конструктор сообщения об ошибке junit java: тестовый класс должен иметь ровно один общедоступный конструктор с нулевым аргументом

Мне действительно может понадобиться помощь с этим параметризованным тестовым примером, который я пытаюсь создать. Независимо от того, какой конструктор я создаю, IDE выдает сообщение об ошибке. Вот мой код:

@RunWith(Parameterized.class)
public class SolverTest {
    final static File folder = new File("C:\\Users\\Azizam\\IdeaProjects\\EightPuzzle\\src\\ModifiedTests");
    final static String destFolder = "C:\\Users\\Azizam\\IdeaProjects\\EightPuzzle\\src\\testresults";
    final static ArrayList<Object[][]> filesList = new ArrayList<>();
    final Object currentBoard = new Object();

    @Parameterized.Parameters
    public static Iterable<Object[][]> data() {
        String path = "";
        int counter = 0;
        for (final File fileEntry : folder.listFiles()) {
            //System.out.println("processing file: " + fileEntry.getName())
            counter++;
            if (counter == 20) break;
            path = destFolder + fileEntry;
            In in = new In(fileEntry.getAbsolutePath());
            int n = in.readInt();
            int moves = in.readInt();
            int[][] tiles = new int[n][n];
            for (int i = 0; i < n; i++)
                for (int j = 0; j < n; j++)
                    tiles[i][j] = in.readInt();
            Board b = new Board(tiles);
            Object[][] fileList = new Object[][]{{b, moves}};
            filesList.add(fileList);
        }
        return filesList;
    }

    @Parameterized.Parameter(0)
    private Board board;
    @Parameterized.Parameter(1)
    private int expectedNumberOfMoves;

    public SolverTest(Board board, int expectedNumberOfMoves) {
        this.board = board;
        this.expectedNumberOfMoves = expectedNumberOfMoves;
    }


    @Test
    public void test() {
        assertEquals(expectedNumberOfMoves, new Solver(board).moves());
    }

}

Я пробовал разные способы создания конструкторов с 1 параметром, 2 и без параметров. Но я никогда не видел такой проблемы или решения. Я перехожу по этой ссылке и этого руководства. Это мой первый параметризованный тест, и отладка, похоже, тоже не дает мне многого. Я также видел эти ссылки, но они не помогли. Я могу предоставить код для остальной части проекта также на GitHub или в gist. Я отлаживал свой код, правильно создавая список файлов, но я мало знаю о том, что с ним происходит потом или что должно произойти. Вот выдержка из ошибки:

java.lang.Exception: Test class should have exactly one public zero-argument constructor

    at org.junit.runners.BlockJUnit4ClassRunner.validateZeroArgConstructor(BlockJUnit4ClassRunner.java:171)
    at org.junit.runners.parameterized.BlockJUnit4ClassRunnerWithParameters.validateConstructor(BlockJUnit4ClassRunnerWithParameters.java:90)
    at org.junit.runners.BlockJUnit4ClassRunner.collectInitializationErrors(BlockJUnit4ClassRunner.java:127)
    at org.junit.runners.ParentRunner.validate(ParentRunner.java:416)
    at org.junit.runners.ParentRunner.<init>(ParentRunner.java:84)
    at org.junit.runners.BlockJUnit4ClassRunner.<init>(BlockJUnit4ClassRunner.java:65)
    at org.junit.runners.parameterized.BlockJUnit4ClassRunnerWithParameters.<init>(BlockJUnit4ClassRunnerWithParameters.java:27)
    at org.junit.runners.parameterized.BlockJUnit4ClassRunnerWithParametersFactory.createRunnerForTestWithParameters(BlockJUnit4ClassRunnerWithParametersFactory.java:16)
    at org.junit.runners.Parameterized.createRunnersForParameters(Parameterized.java:313)
    at org.junit.runners.Parameterized.<init>(Parameterized.java:248)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
    at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:104)
    at org.junit.vintage.engine.discovery.DefensiveAllDefaultPossibilitiesBuilder$DefensiveAnnotatedBuilder.buildRunner(DefensiveAllDefaultPossibilitiesBuilder.java:113)

Вот последняя версия моего кода:

package assignments;

import edu.princeton.cs.algs4.In;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

import java.io.File;
import java.util.ArrayList;

import static junit.framework.TestCase.assertEquals;

@RunWith(Parameterized.class)
public class SolverTest {
    final static File folder = new File("C:\\Users\\Azizam\\IdeaProjects\\EightPuzzle\\src\\ModifiedTests");
    final static String destFolder = "C:\\Users\\Azizam\\IdeaProjects\\EightPuzzle\\src\\testresults";
    final static ArrayList<Object[][]> filesList = new ArrayList<>();
    final Object currentBoard = new Object();

    @Parameterized.Parameters
    public static Iterable<Object[][]> data() {
        String path = "";
        int counter = 0;
        for (final File fileEntry : folder.listFiles()) {
            //System.out.println("processing file: " + fileEntry.getName())
            counter++;
            if (counter == 20) break;
            path = destFolder + fileEntry;
            In in = new In(fileEntry.getAbsolutePath());
            int n = in.readInt();
            int moves = in.readInt();
            int[][] tiles = new int[n][n];
            for (int i = 0; i < n; i++)
                for (int j = 0; j < n; j++)
                    tiles[i][j] = in.readInt();
            Board b = new Board(tiles);
            Object[][] fileList = new Object[][]{{b, moves}};
            filesList.add(fileList);
        }
        return filesList;
    }

    @Parameterized.Parameter(0)
    public Board board;
    @Parameterized.Parameter(1)
    public int expectedNumberOfMoves;

    public SolverTest() {
    }


    @Test
    public void test() {
        assertEquals(expectedNumberOfMoves, new Solver(board).moves());
    }

}

Вот изображение сеанса отладки, показывающее все, что я хочу в списке файлов. Почему-то объект платы не передается в мой конструктор Solver. введите здесь описание изображения


person Shahin    schedule 13.07.2020    source источник


Ответы (1)


Debug Capture Вот что означает ошибка конструктора без аргументов.

Конструктор в тестовом классе выглядит следующим образом:

public SolverTest(Board board, int expectedNumberOfMoves) {
    this.board = board;
    this.expectedNumberOfMoves = expectedNumberOfMoves;
}

Это принимает 2 аргумента, поэтому это не конструктор без аргументов. Ниже приведен конструктор без аргументов:

public SolverTest() {
}

Удаление конструктора с 2 аргументами будет работать, поэтому его не нужно явно указывать, потому что компилятор java автоматически добавит конструктор без аргументов по умолчанию.

ОДНАКО причиной ошибки является сочетание двух подходов для тестового класса Parameterized.

ЛИБО используйте конструктор без аргументов с полями @Parameterized.Parameters (которые, кстати, должны быть общедоступными, а не частными), ИЛИ удалите эти поля и используйте конструкцию с аргументами, которые принимают параметры.

Вот код, измененный для использования первого подхода (то есть с полями @Parameterized.Parameters):

@RunWith(Parameterized.class)
public class SolverTest {
    final static File folder = new File("C:\\Users\\Azizam\\IdeaProjects\\EightPuzzle\\src\\ModifiedTests");
    final static String destFolder = "C:\\Users\\Azizam\\IdeaProjects\\EightPuzzle\\src\\testresults";
    final static ArrayList<Object[][]> filesList = new ArrayList<>();
    final Object currentBoard = new Object();

    @Parameterized.Parameters
    public static Iterable<Object[][]> data() {
        String path = "";
        int counter = 0;
        for (final File fileEntry : folder.listFiles()) {
            //System.out.println("processing file: " + fileEntry.getName())
            counter++;
            if (counter == 20) break;
            path = destFolder + fileEntry;
            In in = new In(fileEntry.getAbsolutePath());
            int n = in.readInt();
            int moves = in.readInt();
            int[][] tiles = new int[n][n];
            for (int i = 0; i < n; i++)
                for (int j = 0; j < n; j++)
                    tiles[i][j] = in.readInt();
            Board b = new Board(tiles);
            Object[][] fileList = new Object[][]{{b, moves}};
            filesList.add(fileList);
        }
        return filesList;
    }

    @Parameterized.Parameter(0)
    public Board board;
    @Parameterized.Parameter(1)
    public int expectedNumberOfMoves;

    public SolverTest() {
    }


    @Test
    public void test() {
        assertEquals(expectedNumberOfMoves, new Solver(board).moves());
    }

}
person ash    schedule 13.07.2020
comment
Ах хорошо. Я не знал, что мне нужно использовать тот или иной способ. Не видел этого в документах или учебнике. Позвольте мне попробовать. - person Shahin; 13.07.2020
comment
@Saaman Я понимаю; после переформатирования и более внимательного прочтения всего этого я вижу, что исключение не является основной проблемой. Мой ответ обновлен, чтобы решить эту проблему. - person ash; 13.07.2020
comment
Ага, может быть непонятно, что там 2 конкурирующих метода. Ошибка конструктора без аргументов возникает, когда используется подход на основе полей, потому что класс Parameterized не ожидает передачи аргументов конструктору. - person ash; 13.07.2020
comment
Кстати, для облегчения чтения и управления тестами я использую огурец — вы можете взглянуть на него. - person ash; 13.07.2020
comment
@Ash-Только что попробовал код. Это дает мне ошибку не запускаемых методов. Похоже, я создаю список файлов таким образом, чтобы он не попадал в модульный тест. Ошибка возникает в моем классе Solver, где я проверяю, не имеет ли Board значение null - person Shahin; 13.07.2020
comment
Хм, отсутствие запускаемых методов означает, что он не находит ни одного тестового метода для запуска. Я вижу в коде метод @Test, поэтому не знаю, что происходит. - person ash; 14.07.2020
comment
@ash-Большое спасибо. Почему-то я не мог нажать галочку раньше. - person Shahin; 15.07.2020