web-dev-qa-db-fra.com

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

Je sais que je peux charger un fichier depuis src/test/resources avec:

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

Mais comment puis-je obtenir le chemin complet du répertoire src/test/resources, c’est-à-dire que je ne veux pas charger de fichier, je veux juste connaître le chemin du répertoire?

194
Rory

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 dans les classes. Chaque classe a une référence à une ClassLoader. Ce code retourne une File à partir du répertoire de ressources. L'appel de getAbsolutePath() sur cette fonction retourne sa valeur absolue Path.

Javadoc pour ClassLoader: http://docs.Oracle.com/javase/7/docs/api/Java/lang/ClassLoader.html

152
ashosborne1

Vous n'avez pas besoin de jouer avec les chargeurs de classe. En fait, c'est une mauvaise habitude à prendre car les ressources du chargeur de classes sont des objets et non Java.io.File lorsqu'elles se trouvent dans une archive JAR.

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

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

resourcesDirectory.getAbsolutePath() renverra 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. Cela rend clair ce que vous faites.

224
Steve C

Je voudrais simplement utiliser Path de Java 7

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

Propre et net!

48
JeanValjean

S'il s'agit d'un projet printanier, 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"));
18
Paramesh Korrakuti

J'ai un projet Maven3 utilisant JUnit 4.12 et Java8 . Pour obtenir le chemin d'un fichier appelé myxml.xml sous src/test/resources, je le fais dans le 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 .

7
Antony

Il existe 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 Quand 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écuterez des tests via IDE est identique à votre projet.
  • 3.1 Quand les tests vont-ils ê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),ETavant d'exécuter des tests via IDE, vous configurez manuellement répertoire pour vos tests. Ce répertoire de travail doit faire référence à votre projet importé contenant les tests. Par défaut, le répertoire de travail de tous les projets importés dans IDE n'en est qu'un. C'est probablement une restriction de IntelliJ IDEA seulement, mais je pense que tous les IDE fonctionnent comme ça. 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 seul grand projet «IDE», nous oblige à nous en souvenir et ne permet pas de vous détendre et d’apprécier votre travail.

La solution proposée par @ ashosborne1 (personnellement, je préfère celle-ci) nécessite 2 exigences supplémentaires qui doivent être remplies avant l'exécution des tests. Voici une liste des étapes à suivre 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

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

  • Au moins une fois, générez le projet via mvn clean install. Il exécutera des tests aussi. Cela peut suffire d’exécuter uniquement votre classe/méthode de test via maven sans construire un projet entier. En conséquence, vos ressources de test seront copiées dans des 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à proposé par @ ashosborne1 (désolé, je ne pouvais pas éditer ce code correctement dans cette liste d'éléments):
public static final String TEVA_FOLDER = "teva"; ... 
URL tevaUrl = YourTest.class.getClassLoader().getResource(TEVA_FOLDER); 
String tevaTestFolder = new File(tevaUrl.toURI()).getAbsolutePath();

Vous pouvez maintenant exécuter votre test via IDE autant de fois que vous le souhaitez. Jusqu'à ce que vous exécutiez MVN propre. Il va déposer le dossier cible.

La création d’un fichier dans un dossier de test et l’exécution de maven pour la première fois sont nécessaires avant de lancer des tests via IDE. Sans ces étapes, si vous créez simplement des ressources de test dans votre IDE, é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 chargeur de classe.

Vous vous demandez peut-être pourquoi j'ai besoin d'importer plus d'un projet Maven dans IDE et pourquoi tant de choses compliquées? Pour moi, l'une des principales motivations est de 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, qui est juste un détenteur de fichiers liés à l'IDE. Ensuite, j'importe des projets Maven déjà existants. J'oblige ces projets importés à conserver les fichiers IDEA dans mon faux projet d'origine uniquement. Par conséquent, je ne vois pas de fichiers liés à l'IDE dans le code. SVN ne devrait pas les voir (ne proposez pas de configurer svn/git pour ignorer de tels fichiers, s'il vous plaît). En outre, c'est juste très pratique.

6
Alexandr

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 existe 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, procédez comme suit:

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

Pour obtenir l'URI de l'un des fichiers TestQuery1, procédez comme suit:

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

Tout le contenu de src/test/resources est copié dans le dossier target/test-classes. Donc, pour obtenir un fichier depuis les ressources de test lors de la construction de maven, vous devez le charger depuis le dossier test-classes, comme ceci:

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

Panne:

  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.

La réponse originale est tirée de this

3
Cherry

Vous ne pouvez pas utiliser un fichier formant un dossier de ressources pour des tests dans un cas courant. La raison en est que les fichiers de ressources du dossier de ressources sont stockés dans un fichier JAR. Donc, ils n'ont pas de vrai chemin dans le système de fichiers.

La solution la plus simple peut être:

  1. Copiez un fichier à partir des ressources dans le dossier temporaire et obtenez un chemin d'accès à ce fichier temporaire.
  2. Faites des tests en utilisant un chemin temporaire.
  3. Supprimer le fichier temporaire.

TemporaryFolder à partir de JUnit peut être utilisé pour créer des fichiers temporaires et les supprimer une fois le test terminé. Les classes de la bibliothèque guava permettent de copier un dossier de ressources sous forme de fichier. 

Veuillez noter que si nous utilisons un sous-dossier dans le dossier des ressources, tel que good one, nous n'avons pas à ajouter / en tête au chemin d'accès aux ressources.

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
v.ladynev

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 dans votre dossier src/test/resources, il reviendra automatiquement à celui de votre dossier src/main/resources.

0
whitebrow

Utilisez .getAbsolutePath () sur votre objet File.

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