Comment obtenir le chemin du répertoire src/test/resources dans JUnit?

Je sais que je peux charger un fichier à partir de src / test / resources avec:

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

, Mais comment puis-je obtenir le chemin complet vers le répertoire src/test/resources répertoire, c'est à dire je ne veux pas charger un fichier, je veux juste savoir le chemin d'accès du répertoire?

164
demandé sur Rory 2015-02-23 15:18:02

11 réponses

Essayez de travailler avec la classe ClassLoader:

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

Un ClassLoader est responsable du chargement des classes. Chaque classe a une référence à un ClassLoader. Ce code renvoie un File à partir du répertoire des ressources. L'appel à getAbsolutePath() renvoie son Path absolu.

Javadoc pour ClassLoader: http://docs.oracle.com/javase/7/docs/api/java/lang/ClassLoader.html

128
répondu ashosborne1 2018-05-06 17:44:54

Vous n'avez pas besoin de jouer avec les chargeurs de classe. En fait, c'est une mauvaise habitude d'entrer dans Parce que les ressources du chargeur de classe sont Pas objets java.io.File lorsqu'ils sont dans une archive jar.

Maven définit automatiquement le répertoire de travail actuel avant d'exécuter des tests, de sorte que vous pouvez simplement utiliser:

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

resourcesDirectory.getAbsolutePath() retournera la valeur correcte si c'est ce dont vous avez vraiment besoin.

Je recommande de créer un répertoire src/test/data Si vous voulez que vos tests accèdent aux données via le système de fichiers. Ce il ressort clairement de ce que vous faites.

193
répondu Steve C 2015-02-23 13:13:11

Je voudrais simplement utiliser Path à partir de Java 7

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

Propre et propre!

33
répondu JeanValjean 2018-05-16 11:13:54

S'il s'agit d'un projet spring, nous pouvons utiliser le code ci-dessous pour obtenir les fichiers du dossier src/test/resource.

File file = ResourceUtils.getFile(this.getClass().getResource("/some_file.txt"));
11
répondu Paramesh Korrakuti 2016-08-31 07:17:21

J'ai un projet Maven3 utilisant JUnit 4.12 et Java8. Afin d'obtenir le chemin d'un fichier appelé myxml.xml sous src/test/resources, je le fais à partir du cas de test:

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

Testé sur Ubuntu 14.04 avec IntelliJ IDE. Référence ici.

6
répondu Antony 2016-04-27 10:34:52

Il y a des différences et des contraintes dans les options offertes par @ Steve C et @ashosborne1. Ils doivent être spécifiés, je crois.

Quand pouvons-nous utiliser: File resourcesDirectory = new File("src/test/resources");?

  • 1 lorsque les tests vont être exécutés via maven uniquement mais pas via IDE.
  • 2.1 lorsque les tests vont être exécutés via maven ou
  • 2.2 VIA IDE et un seul projet est importé dans IDE. (J'utilise le terme "importé", car il est utilisé dans IntelliJ IDEA. Je pense que les utilisateurs d'eclipse importent également leur projet maven). Cela fonctionnera, car le répertoire de travail lorsque vous exécutez des tests via IDE est le même que votre projet.
  • 3.1 lorsque les tests vont être exécutés via maven ou
  • 3.2 VIA IDE, et plusieurs projets sont importés dans IDE (lorsque vous n'êtes pas étudiant, vous importez généralement plusieurs projets), et {[20] } avant d'exécuter des tests via IDE, vous configurez manuellement le répertoire de travail pour vos tests. Ce répertoire de travail doit faire référence à votre projet importé qui contient les tests. Par défaut, le répertoire de travail de tous les projets importés dans IDE est un seul. Probablement c'est une restriction de IntelliJ IDEA seulement, mais je pense que tous les IDE fonctionnent comme ceci. Et cette configuration qui doit être faite manuellement, n'est pas bonne du tout. Travailler avec plusieurs tests existants dans différents projets maven, mais importés dans un grand projet "IDE", nous force à nous en souvenir et ne permet pas de vous détendre et de profiter de votre travail.

Solution offerte par @ ashosborne1 (personnellement, je préfère celui-ci) nécessite 2 Exigences supplémentaires qui doivent être faites avant d'exécuter des tests. Voici une liste des étapes pour utiliser cette solution:

  • Créez un dossier de test ("teva") et un fichier ("readme") à l'intérieur de " src / test / resources/":

    Src / test / resources/teva / readme

    Fichier doit être créé dans le dossier de test, sinon, il ne fonctionnera pas. Maven ignore les dossiers vides.

  • au moins une fois construire le projet via mvn clean install. Il exécutera également des tests. Il peut être suffisant pour exécuter uniquement votre tester la classe / méthode via maven sans construire un projet entier. En conséquence, vos ressources de test seront copiées dans les classes de test, voici un chemin: target/test-classes/teva/readme
  • Après cela, vous pouvez accéder au dossier en utilisant le code, déjà offert par @ ashosborne1 (je suis désolé, que je ne pouvais pas modifier ce code à l'intérieur de cette liste d'éléments correctement):
public static final String TEVA_FOLDER = "teva"; ... 
URL tevaUrl = YourTest.class.getClassLoader().getResource(TEVA_FOLDER); 
String tevaTestFolder = new File(tevaUrl.toURI()).getAbsolutePath();

Maintenant, vous pouvez exécuter votre test via IDE autant de fois que vous le souhaitez. Jusqu'à ce que vous exécutiez mvn clean. Il va laisser tomber la cible dossier.

Créer un fichier dans un dossier de test et exécuter Maven la première fois, avant d'exécuter des tests via IDE sont des étapes nécessaires. Sans ces étapes, si vous créez simplement des ressources de test dans votre IDE, puis écrivez test et exécutez-le uniquement via IDE, vous obtiendrez une erreur. L'exécution de tests via mvn copie les ressources de test dans target / test-classes / teva / readme et elles deviennent accessibles pour un classloader.

, Vous pouvez demander, pourquoi ai-je besoin d'importer plus d'un projet maven dans IDE et pourquoi tant de compliqué des choses? Pour moi, l'une des principales motivations: garder les fichiers liés à IDA loin du code. Je crée d'abord un nouveau projet dans mon IDE. C'est un faux projet, c'est juste un détenteur de fichiers liés à IDE. Ensuite, j'importe des projets Maven déjà existants. Je force ces projets importés à conserver les fichiers D'idées dans mon faux projet original uniquement. En conséquence, Je ne vois pas les fichiers liés à IDE parmi le code. SVN ne devrait pas les voir (ne proposez pas de configurer svn / git pour ignorer de tels fichiers, svp). Aussi, il est juste très pratique.

6
répondu Alexandr 2016-06-09 00:08:10

La solution la plus simple et la plus propre que j'utilise, supposons que le nom de la classe de test soit TestQuery1 et qu'il y ait un répertoire resources dans votre dossier test comme suit:

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

Pour obtenir l'URI de TestQuery1 Faites:

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

Pour obtenir L'URI de l'un des fichiers TestQuery1, Faites:

File exampleDir = new File(currentTestResourceFolder.toURI());
URI queryJSONFileURI = exampleDir.toURI().resolve("query.json");
3
répondu Noor 2017-03-18 13:21:25

Utilisez ce qui suit pour injecter Hibernate avec Spring dans vos tests unitaires:

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

Si vous n'avez pas le hibernate.cfg.xml présent dans votre dossier src/test/resources, il retombera automatiquement sur celui de votre dossier src/main/resources.

0
répondu whitebrow 2018-01-31 08:12:43

Tout le contenu de src/test/resources est copié dans le dossier target/test-classes. Donc, pour obtenir le fichier à partir des ressources de test pendant la construction de maven, vous devez le charger à partir du dossier test-classes, comme ceci:

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

Décomposer:

  1. getClass().getProtectionDomain().getCodeSource().getLocation().toURI() - Donnez votre URI à target/test-classes.
  2. resolve(Paths.get("somefile")) - résout someFile dans le dossier target/test-classes.

Anwser Original est tiré de ce

0
répondu Cherry 2018-07-06 21:51:58

Utilisation .getAbsolutePath() sur votre objet fichier.

getClass().getResource("somefile").getFile().getAbsolutePath()
0
répondu GreatDantone 2018-07-06 21:52:46

Vous ne pouvez pas utiliser un fichier dans un dossier de ressources pour les tests dans un cas commun. La raison en est que les fichiers de ressources dans le dossier de ressources sont stockés dans un fichier jar. Donc, ils n'ont pas de chemin réel dans le système de fichiers.

La solution La plus simple peut être:

  1. copiez un fichier des ressources dans le dossier temporaire et obtenez un chemin d'accès à ce fichier temporaire.
  2. effectuez des tests en utilisant un chemin temporaire.
  3. supprimez le fichier temporaire.

TemporaryFolder à partir de JUnit peut être utilisé pour créer des fichiers temporaires et le supprimer après test est complited. Les Classes de la bibliothèque guava sont utilisées pour copier un dossier de ressources de formulaire de fichier.

Veuillez noter que si nous utilisons un sous-dossier dans le dossier resources, comme good one, nous n'avons pas besoin d'ajouter le premier / au chemin de la ressource.

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;
    }

}
0
répondu v.ladynev 2018-09-06 12:39:50