Почему я не могу получить доступ к src / test / resources в тестовом запуске Junit с Maven?

#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. Спасибо за это. ваша логика верна (см. Комментарий Выше), но, к сожалению, я все еще не могу заставить это работать