2015-02-23 4 views
125

Я знаю, что могу загрузить файл с SRC/тест/ресурсов с:Как получить путь к каталогу src/test/resources в JUnit?

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

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

+1

Из любопытства: зачем вы хотите знать? – fge

+2

@fge необходимо передать его тестируемому объекту, который использует его для загрузки файла – Rory

+0

@fge У меня был аналогичный случай для JBoss - получить имя приложения (war file) приложения для чтения конфигурации из/etc/mycompany/deployment_name/config (у нас есть много экземпляров одного и того же приложения, развернутого в одно и то же время). – Nikolay

ответ

97

Попробуйте работать с загрузчиком классов объекта:

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

Edit, чтобы объяснить немного больше:

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

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

+10

Это не обязательно хорошая идея. Если ресурс находится в банке, это приведет к печальным временам. –

+1

@OliverCharlesworth Итак, что можно сделать в случае банки? –

+0

@AnmolSinghJaggi - см. Мой комментарий ниже исходного вопроса :) –

152

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

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

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

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

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

+2

новый файл («src/test/resources/fileXYZ»); не будет работать. Ни от Eclipse, ни от Maven, если вы просто положили это на тест JUnit. –

+7

Он отлично работает с Maven. В eclipse вам нужно будет установить текущий рабочий каталог в тестовом runner, но команда maven сделает это за вас. –

+2

Я так не думаю. И почему бы вам это сделать, если вы можете сделать просто «новый файл (getClass(). GetClassLoader(). GetResource (« fileNameXYZ.xml »)», не нужно ничего настраивать. Ни в Eclipse, ни в Maven. –

4

У меня есть проект 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. Ссылка here.

+0

Даже работал с Maven3, Java 9 и JUnit 5. – lkamal

4

Существуют различия и ограничения в вариантах, предлагаемых @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») и файл («ридми») внутри «SRC/тест/ресурсы /»:

    Src/test/resources/teva/readme

    Файл должен быть создан в тестовой папке, иначе это не сработает. 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, чтобы игнорировать такие файлы, пожалуйста). Также это очень удобно.

+0

Привет, Александр, у меня проблемы с файлом ресурсов в target/classes и src/main/resource, и вам кажется, что об этом говорят только один. Сначала у меня есть файлы на src/main/resource, после проекта сборки он копирует эти файлы в целевые/классы. И getClass(). GetClassLoader(). GetResource (fileName) работает только с целевой папкой, пока я хочу работать с src/main. Можете ли вы дать мне ссылку где-нибудь объяснить механизм файла getResource? как настроить папку ресурсов? Tks: D –

+1

@ Huy Hóm Hỉnh, я бы порекомендовал, не делайте этого. Я боюсь, что вы идете в неправильном направлении. Есть определенные места, где располагаются файлы ресурсов, места известны всем остальным. Легче поддерживать такие проекты. Даже для вас это будет проще, вам просто нужно понять структуру проектов maven. Но, конечно, вы можете настроить местоположение ресурсов по умолчанию с помощью [https://maven.apache.org/plugins/maven-resources-plugin/examples/resource-directory.html] – Alexandr

+0

@ HuyHómHỉnh. Также рассмотрите решение здесь : https://stackoverflow.com/questions/23289098/how-to-copy-resource-to-src-target-directory-with-maven#answer-23320582 Но чтобы настроить src/main как ресурс ... Попробуйте чтобы избежать этого, кажется, вы делаете что-то неправильно. – Alexandr

9

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

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

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

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

Аккуратный и чистый!

+0

Будет ли этот точный код работать в Windows? JavaDoc для 'Paths.get (...)' предлагает (мне все равно), что это не будет. –

+0

@SteveC вы можете использовать константу 'File.separator' для построения строки, которая будет использоваться в качестве пути – JeanValjean

+0

Я знаю это, но это очень уродливо. Напротив, 'новый файл (« src/test/resources ») делает правильную вещь на всех платформах. –

1

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

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

Чтобы получить URI из TestQuery1 сделать:

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

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

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

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

GetClass() getResource ("некий-файл") GetFile() getAbsolutePath()

0

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

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

Если вы не» t есть hibernate.cfg.xml, присутствующий в вашей папке src/test/resources, он автоматически вернется к папке в вашей папке src/main/resources.

Смежные вопросы