Объект Class‹Test› не того же типа, что и тестовый объект? Юнит

Я пытаюсь написать код, который рекурсивно добавляет TestSuites в проект к набору наборов, расположенных в корне иерархии пакетов.

Я уже написал код, который возвращает объект Collection, содержащий объект File для каждого набора тестов, найденного в моем проекте.

Теперь я пытаюсь просмотреть их и добавить в TestSuite в файл с именем AllTests.java:

public static Test suite() throws IOException, ClassNotFoundException {
    TestSuite suite = new TestSuite();

            //Code not included for getTestSuites() in this snippet.
    Collection<File> testSuites = getTestSuites();
    for(File f: testSuites) {

            //Truncate the path of the test to the beginning of the package name
            String testName = f.getAbsolutePath().substring(f.getAbsolutePath().lastIndexOf("net"));

            //Replace backslashes with fullstops
            testName = testName.replaceAll("\\\\", ".");

            //Take the .class reference off the end of the path to the class
            testName = testName.replaceAll(".class", "");

            //Add TestSuite to Suite of Suites

            Class<? extends Test> test = (Class<? extends Test>) AllTests.class.getClassLoader().loadClass(testName);
            suite.addTest(test);
    }

К сожалению, я получаю следующую ошибку компилятора в строке suite.addTest(test):

Метод addTest(Test) в типе TestSuite неприменим для аргументов (Класс ‹ Capture#3-of ? extends Test>)

Совершаю ли я фундаментальную ошибку, предполагая, что ссылка Class‹ Test> и ссылка Test — это одно и то же?


person 8bitjunkie    schedule 24.06.2011    source источник


Ответы (4)


Да, вы совершаете фундаментальную ошибку, предполагая, что ссылка Class‹ Test > и ссылка Test — это одно и то же.

Вам нужен экземпляр класса, который расширяет Test, а не экземпляр объекта класса, определение которого расширяет Test (классы тоже являются объектами в java).

person Bohemian♦    schedule 24.06.2011

TestSuite.addTest нужен экземпляр тестового класса; не просто объект класса.

Вы можете попробовать использовать Class.newInstance(), если ваши тесты могут (они должны) создавать экземпляры без параметров.

--

Возможно, лучшая стратегия — начать использовать Maven; который автоматически запускает все классы Test в исходной папке src/test/java. Но это может быть довольно большой капитальный ремонт :).

person Yhn    schedule 24.06.2011

Class<Test> описывает концепцию класса Test -- его поля, методы и другие вещи, описанные кодом Java при определении класса Test. Существует обычно (чтобы не касаться загрузчиков классов) один экземпляр Class<Test> в JVM, поскольку в основном существует только один класс Test.

То же самое относится к каждому подклассу Test — обычно существует один экземпляр Class<TestSubClass> для каждого TestSubClass.

С другой стороны, может быть любое количество Test объектов.

Java позволяет вам создавать объекты Test из Class<Test>, вызывая newInstance для вашего экземпляра Class<Test>. Итак, в основном, измените свою строку с:

suite.addTest(test);

to

suite.addTest(test.newInstance());

И обрабатывать все возможные исключения.

person Nick    schedule 24.06.2011
comment
Спасибо за это. Пытался использовать test.newInstance().suite() (для вызова статического метода suite() для объекта), но неожиданно я получаю сообщение об ошибке компилятора (правильно), указывающее, что Test не имеет метода suite(). К сожалению, TestSuite() тоже. Я думаю, мне нужно найти способ привести тестовый объект к типу Class‹Вытащить строку из моего массива и закачать сюда имя TestSuite› - но я понятия не имею, возможно ли это вообще! - person 8bitjunkie; 24.06.2011
comment
Из JavaDocs я вижу метод TestSuite.addTest(Test) -- что означает, что вы можете сделать suite.addTest((Test) test.newInstance()) - person Nick; 24.06.2011

Используемый вами метод ожидает экземпляр тестового (под)класса. Вероятно, вам нужен addTestSuite (Class testClass), который позволяет добавлять классы.

person aliher    schedule 24.06.2011
comment
Я пробовал это, но он возвращается с ошибками Null, говорящими, что Suite не может найти никаких тестов в дочернем Suite. Мне удалось заставить его работать с помощью suite.addTest(path.to.Suite.SuiteName.suite()) - теперь просто пытаюсь создать эту строку программно :-) - person 8bitjunkie; 24.06.2011