Подтвердить что ты не робот

Как получить путь к каталогу src/test/resources в JUnit?

Я знаю, что могу загрузить файл из src/test/resources с помощью

getClass().getResource("somefile").getFile()

Но как я могу получить полный путь к каталогу src/test/resources , то есть я не хочу загружать файл, я просто хочу узнать путь к каталогу?

4b9b3361

Ответ 1

Попробуйте поработать с классом ClassLoader:

ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("somefile").getFile());
System.out.println(file.getAbsolutePath());

ClassLoader отвечает за загрузку в классах. Каждый класс имеет ссылку на ClassLoader. Этот код возвращает File из каталога ресурсов. Вызов getAbsolutePath() для него возвращает его абсолютный Path.

Javadoc для ClassLoader: http://docs.oracle.com/javase/7/docs/api/java/lang/ClassLoader.html

Ответ 2

Вам не нужно возиться с загрузчиками классов. На самом деле это плохая привычка, потому что ресурсы загрузчика классов не java.io.File объекты, когда они находятся в архиве jar.

Maven автоматически устанавливает текущий рабочий каталог перед запуском тестов, поэтому вы можете просто использовать:

    File resourcesDirectory = new File("src/test/resources");

resourcesDirectory.getAbsolutePath() вернет правильное значение, если это то, что вам действительно нужно.

Я рекомендую создать каталог src/test/data, если вы хотите, чтобы ваши тесты получали доступ к данным через файловую систему. Это дает понять, что вы делаете.

Ответ 3

Я бы просто использовал Path из Java 7

Path resourceDirectory = Paths.get("src","test","resources");

С иголочки!

Ответ 4

Если это проект spring, мы можем использовать приведенный ниже код для получения файлов из папки src/test/resource.

File file = ResourceUtils.getFile(this.getClass().getResource("/some_file.txt"));

Ответ 5

У меня есть проект Maven3 с использованием JUnit 4.12 и Java8. Чтобы получить путь к файлу с именем myxml.xml src/test/resources, я делаю это из тестового примера:

@Test
public void testApp()
{
    File inputXmlFile = new File(this.getClass().getResource("/myxml.xml").getFile());
    System.out.println(inputXmlFile.getAbsolutePath());
    ...
}

Протестировано на Ubuntu 14.04 с IntelliJ IDE. Ссылка здесь.

Ответ 6

Весь контент в src/test/resources копируется в папку target/test-classes. Таким образом, чтобы получить файл из тестовых ресурсов во время сборки maven, вы должны загрузить его из папки test-classes, например:

Paths.get(
    getClass().getProtectionDomain().getCodeSource().getLocation().toURI()
).resolve(
    Paths.get("somefile")
).toFile()

Сломать:

  1. getClass().getProtectionDomain().getCodeSource().getLocation().toURI() - дает вам URI для target/test-classes.
  2. resolve(Paths.get("somefile")) - разрешает someFile в someFile target/test-classes.

Оригинальный ответ взят из этого

Ответ 7

Существуют различия и ограничения в вариантах, предлагаемых @Steve C и @ashosborne1. Думаю, они должны быть указаны.

Когда мы можем использовать: File resourcesDirectory = new File("src/test/resources");?

  • 1 Когда тесты будут запускаться только через maven, но не через IDE.
  • 2.1 Когда тесты будут запущены через maven или
  • 2.2 через IDE, и только один проект импортируется в IDE. (Я использую "импортированный" термин, потому что он используется в IntelliJ IDEA. Я думаю, что пользователи eclipse также импортируют свой проект maven). Это будет работать, потому что рабочий каталог при запуске тестов через IDE совпадает с вашим проектом.
  • 3.1 Когда тесты будут запущены через maven или
  • 3.2 через IDE, и более чем один проект импортируется в среду IDE (когда вы не являетесь студентом, вы обычно импортируете несколько проектов), И, прежде чем запускать тесты через IDE, вы вручную настраиваете рабочие каталог для ваших тестов. Этот рабочий каталог должен ссылаться на ваш импортированный проект, содержащий тесты. По умолчанию рабочий каталог всех проектов, импортированных в IDE, является только одним. Вероятно, это ограничение только IntelliJ IDEA, но я думаю, что все IDE работают так. И эта конфигурация, которая должна выполняться вручную, совсем не хороша. Работа с несколькими тестами, существующими в разных проектах maven, но импортированными в один большой проект "IDE", заставляет нас помнить об этом и не позволяет расслабиться и получить удовольствие от вашей работы.

Решение, предлагаемое @ashosborne1 (лично я предпочитаю этот), требует 2 дополнительных требований, которые должны быть выполнены до запуска тестов. Ниже приведен список шагов для использования этого решения:

  • Создайте тестовую папку ( "teva" ) и файл ( "readme" ) внутри "src/test/resources/":

    SRC/тест/ресурсы/Teva/риая

    Файл должен быть создан в тестовой папке, иначе это не сработает. Maven игнорирует пустые папки.

  • Как минимум один раз построить проект через mvn clean install. Он также проведет тесты. Может быть достаточно запустить только ваш тестовый класс/метод через maven без создания целого проекта. В результате ваши тестовые ресурсы будут скопированы в тестовые классы, вот путь: target/test-classes/teva/readme
  • После этого вы можете получить доступ к папке с помощью кода, уже предложенного @ashosborne1 (извините, что я не смог правильно отредактировать этот код внутри этого списка элементов):
public static final String TEVA_FOLDER = "teva"; ... 
URL tevaUrl = YourTest.class.getClassLoader().getResource(TEVA_FOLDER); 
String tevaTestFolder = new File(tevaUrl.toURI()).getAbsolutePath();

Теперь вы можете запускать свой тест через IDE столько раз, сколько хотите. Пока вы не запустите mvn clean. Он потеряет целевую папку.

Создание файла внутри тестовой папки и запуск maven в первый раз, прежде чем запускать тесты через IDE, необходимы шаги. Без этих шагов, если вы только в своей среде IDE создадите тестовые ресурсы, затем напишите тест и запустите его только через IDE, вы получите сообщение об ошибке. Выполнение тестов через mvn копирует тестовые ресурсы в целевые/тестовые классы /teva/readme, и они становятся доступными для загрузчика классов.

Вы можете спросить, зачем мне импортировать более одного проекта maven в IDE и почему так много сложного? Для меня одна из основных причин: хранить файлы, связанные с IDA, вдали от кода. Сначала я создаю новый проект в своей среде IDE. Это поддельный проект, который является только владельцем файлов, связанных с IDE. Затем я импортирую уже существующие проекты maven. Я заставляю эти импортированные проекты хранить файлы IDEA только в моем оригинальном поддельном проекте. В результате я не вижу файлы, связанные с IDE, среди кода. SVN не должен их видеть (не предлагайте настроить svn/ git, чтобы игнорировать такие файлы, пожалуйста). Также это очень удобно.

Ответ 8

Самое простое и чистое решение, которое я использую, предположим, что имя тестового класса TestQuery1 и в папке test есть каталог resources следующим образом:

├── java
│   └── TestQuery1.java
└── resources
    └── TestQuery1
        ├── query.json
        └── query.rq

Чтобы получить URI TestQuery1 do:

URL currentTestResourceFolder = getClass().getResource("/"+getClass().getSimpleName());

Чтобы получить URI одного из файлов TestQuery1, выполните:

File exampleDir = new File(currentTestResourceFolder.toURI());
URI queryJSONFileURI = exampleDir.toURI().resolve("query.json");

Ответ 9

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

Наиболее простым решением может быть:

  1. Скопируйте файл из ресурсов во временную папку и получите путь к этому временному файлу.
  2. Делайте тесты, используя временный путь.
  3. Удалить временный файл.

TemporaryFolder из JUnit может использоваться для создания временных файлов и удаления их после завершения теста. Классы из библиотеки guava используются для копирования папки ресурса формы файла.

Обратите внимание, что если мы используем подпапку в папке ресурсов, например good, нам не нужно добавлять ведущий / к пути ресурса.

public class SomeTest {

    @Rule
    public TemporaryFolder tmpFolder = new TemporaryFolder();


    @Test
    public void doSomethinge() throws IOException {
        File file = createTmpFileFromResource(tmpFolder, "file.txt");
        File goodFile = createTmpFileFromResource(tmpFolder, "good/file.txt");

        // do testing here
    }

    private static File createTmpFileFromResource(TemporaryFolder folder,
                                                  String classLoaderResource) throws IOException {
        URL resource = Resources.getResource(classLoaderResource);

        File tmpFile = folder.newFile();
        Resources.asByteSource(resource).copyTo(Files.asByteSink(tmpFile));
        return tmpFile;
    }

}

Ответ 10

Используйте .getAbsolutePath() для вашего объекта File.

getClass().getResource("somefile").getFile().getAbsolutePath()

Ответ 11

Используйте следующее, чтобы внедрить Hibernate с помощью Spring в своих модульных тестах:

@Bean
public LocalSessionFactoryBean getLocalSessionFactoryBean() {
    LocalSessionFactoryBean localSessionFactoryBean = new LocalSessionFactoryBean();
    localSessionFactoryBean.setConfigLocation(new ClassPathResource("hibernate.cfg.xml"));
    localSessionFactoryBean.setPackagesToScan("com.example.yourpackage.model");
    return localSessionFactoryBean;
}

Если у вас нет hibernate.cfg.xml в вашей папке src/test/resources он автоматически вернется к той, что находится в вашей папке src/main/resources.