#java #junit4 #mockito
#java #junit4 #mockito
Вопрос:
У меня возникли проблемы с запуском следующего кода:
configService.setMainConfig("src/test/resources/MainConfig.xml");
Из метода Junit @Before.
Так ли Maven создает свою целевую папку?
Ответ №1:
Доступ MainConfig.xml
напрямую. Содержимое src/test/resources
каталога помещается в корень вашего пути к классу.
Точнее: содержимое src/test/resources
копируется в target/test-classes
, поэтому, если у вас следующая структура проекта:
.
└── src
└── test
├── java
│ └── foo
│ └── C.java
└── resources
├── a.xml
└── foo
└── b.xml
Результатом будет следующее содержимое пути к тестовому классу:
/foo/C.class
/a.xml
/foo/b.xml
Чтобы фактически получить доступ к файлам из исходного кода Java, используйте getClass().getResource("/MainConfig.xml").getFile()
.
Комментарии:
1. Спасибо за этот краткий ответ. Вы действительно правы, что файл можно увидеть в /target/test-classes . Однако я все еще не могу ссылаться на него из своего кода. Перепробовал всевозможные комбинации: ‘ConfigService.setMainConfig(«MainConfig.xml «); ‘ ‘ConfigService.setMainConfig(«target/test-classes/MainConfig.xml «); ‘ ConfigService.setMainConfig(«classpath:MainConfig.xml «); и т.д. и т.п.
2. Попробуйте
getClass().getResource("/MainConfig.xml").getFile()
3. Если вы используете Tycho и eclipse-plugin в качестве типа упаковки, не забудьте добавить src/test/resources в файл build.properties.
4. Спасибо, но я запускаю свой junit в jenkins его сбой, по какой-то причине файлы из src/test/resource копируются в /target/classes вместо /target/test-classes
Ответ №2:
Сегодня я столкнулся с той же проблемой и нашел несколько решений.
Во-первых, вот моя файловая структура:
.
└── src
│ └── test
│ ├── java
│ │ └── mypackage
│ │ └── MyClassTest.java
│ └── resources
│ └── image.jpg
└── target
└── test-classes
├── image.jpg
└── mypackage
└── MyClassTest.class
Что не работает: (Java 11 synthax)
var imgFile = new File("image.jpg"); // I was expecting that Junit could find the file.
var absPath = file.getAbsolutePath(); // /home/<user>/../<project-root>/image.jpg
var anyFileUnderThisPath = file.exists(); // false
Что мы можем заметить, так это то, что абсолютный путь вообще не указывает на мое изображение! Но если бы у меня был образ в корне проекта, тогда это сработало бы.
Решение 1: пути (введены в Java 7)
var relPath = Paths.get("src", "test", "resources", "image.jpg"); // src/test/resources/image.jgp
var absPath = relPath.toFile().getAbsolutePath(); // /home/<user>/../<project-root>/src/test/resources/image.jpg
var anyFileUnderThisPath = new File(absPath).exists(); // true
Как мы видим, он указывает на нужный файл.
Решение 2: загрузчик классов
var classLoader = getClass().getClassLoader();
var url = classLoader.getResource("image.jpg"); // file:/home/<user>/../<project-root>/target/test-classes/image.jpg
var file = new File(url.getFile()); // /home/<user>/../<project-root>/target/test-classes/image.jpg
var anyFileUnderThisPath = file.exists(); // true
Обратите внимание, что теперь поиск файла выполняется в целевом каталоге! и это работает.
Решение 3: файл (адаптация нерабочего примера)
var absPath = new File("src/test/resources/image.jpg").getAbsolutePath();
var var anyFileUnderThisPath = new File(absPath).exists(); // true
Который также работает после указания абсолютного пути и указания src/test/resources/
в качестве префикса.
Краткие сведения
Все три решения работают, но необходимость ставить src/test/resources/
, по моему мнению, не элегантна, и именно поэтому я бы предпочел 2-е решение ( ClassLoader
) .
Источники:
Ответ №3:
Я предполагаю setMainConfig
, что ожидает путь к ресурсу, который он загрузит с помощью ClassLoader, а не относительный путь к файлу. Это помогло бы, если бы вы связались с javadoc этого таинственного configService.setMainConfig
метода.
Если мое предположение верно, то путь должен быть просто MainConfig.xml . Mave копирует содержимое src/test/resources
в папку target/test-classes
(IIRC). И эта папка test-classes находится в пути к классам модульных тестов.
Комментарии:
1. Спасибо за это. ваша логика верна (см. Комментарий Выше), но, к сожалению, я все еще не могу заставить это работать