web-dev-qa-db-fra.com

Pourquoi ne puis-je pas accéder à src / test / resources dans le test Junit avec Maven?

J'ai des problèmes pour exécuter le code suivant:

configService.setMainConfig("src/test/resources/MainConfig.xml");

Depuis une méthode Junit @Before.

Est-ce ainsi que Maven construit son dossier cible?

45
Michael W

Accédez directement à MainConfig.xml. Le contenu du répertoire src/test/resources Est placé à la racine de votre CLASSPATH.

Plus précisément: le contenu de src/test/resources Est copié dans target/test-classes, Donc si vous avez la structure de projet suivante:

.
└── src
    └── test
        ├── Java
        │   └── foo
        │       └── C.Java
        └── resources
            ├── a.xml
            └── foo
                └── b.xml

Il en résultera le contenu CLASSPATH de test suivant:

  • /foo/C.class
  • /a.xml
  • /foo/b.xml

Pour accéder réellement aux fichiers depuis la source Java source, utilisez getClass().getResource("/MainConfig.xml").getFile().

66
Tomasz Nurkiewicz

Je suppose que setMainConfig attend le chemin d'une ressource, qu'elle se chargera en utilisant le ClassLoader, et non un chemin de fichier relatif. Il serait utile que vous vous liez au javadoc de ce mystérieux configService.setMainConfig méthode.

Si ma supposition est correcte, le chemin doit être simplement MainConfig.xml. Mave copie le contenu de src/test/resources au target/test-classes (IIRC) dossier. Et ce dossier de classes de test se trouve dans le chemin de classe des tests unitaires.

3
JB Nizet

J'ai rencontré le même problème aujourd'hui et j'ai trouvé des solutions.

Tout d'abord, voici ma structure de fichiers:

.
└── src
│   └── test
│       ├── Java
│       │   └── mypackage
│       │       └── MyClassTest.Java
│       └── resources
│           └── image.jpg
└── target
    └── test-classes
            ├── image.jpg
            └── mypackage
                └── MyClassTest.class  

Ce qui ne fonctionne pas: (syntaxe Java 11)

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

Ce que l'on peut remarquer, c'est que le chemin absolu ne pointe pas du tout sur mon image! Mais si j'avais une image sous à la racine du projet, cela aurait fonctionné.

Solution 1: Chemins (introduit dans 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

Comme nous pouvons le voir, il pointe sur le bon fichier.

Solution 2: ClassLoader

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

Notez que maintenant le fichier est recherché sous le répertoire cible! et il fonctionne.

Solution 3: Fichier (Adaptation de l'exemple non fonctionnel)

var absPath = new File("src/test/resources/image.jpg").getAbsolutePath();
var var anyFileUnderThisPath = new File(absPath).exists(); // true

Cela fonctionne également après avoir pris le chemin absolu et mis src/test/resources/ comme préfixe.

Résumé

Les trois solutions fonctionnent mais doivent mettre src/test/resources/ n'est, à mon avis, pas élégant, et c'est pourquoi je préférerais la 2ème solution (ClassLoader).

Sources:

2
KeyMaker00