How to get the path of src/test/resources directory in JUnit?

前端 未结 14 1786
时光取名叫无心
时光取名叫无心 2020-11-28 01:25

I know I can load a file from src/test/resources with:

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

But how can I get the full path to th

相关标签:
14条回答
  • 2020-11-28 02:09
    List<String> lines = Files.readAllLines(Paths.get("src/test/resources/foo.txt"));
    lines.forEach(System.out::println);
    
    0 讨论(0)
  • 2020-11-28 02:11

    Try working with the ClassLoader class:

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

    A ClassLoader is responsible for loading in classes. Every class has a reference to a ClassLoader. This code returns a File from the resource directory. Calling getAbsolutePath() on it returns its absolute Path.

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

    0 讨论(0)
  • 2020-11-28 02:11

    I would simply use Path from Java 7

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

    Neat and clean!

    0 讨论(0)
  • 2020-11-28 02:11

    You can't use a file from a resource folder for tests in a common case. The reason is that resource files in the resource folder are stored inside a jar. So they don't have a real path in the file system.

    The most simple solution can be:

    1. Copy a file from resources to the temporary folder and get a path to that temporary file.
    2. Do tests using a temporary path.
    3. Delete the temporary file.

    TemporaryFolder from JUnit can be used to create temporary files and delete it after test is complited. Classes from guava library are used to copy a file form resource folder.

    Please, notice that if we use a subfolder in the resources folder, like good one, we don't have to add leading / to the resource path.

    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 讨论(0)
  • 2020-11-28 02:16

    There are differences and constraints in options offered by @Steve C and @ashosborne1. They must be specified, I believe.

    When can we can use: File resourcesDirectory = new File("src/test/resources");?

    • 1 When tests are going to be run via maven only but not via IDE.
    • 2.1 When tests are going to be run via maven or
    • 2.2 via IDE and only one project is imported into IDE. (I use “imported” term, cause it is used in IntelliJ IDEA. I think users of eclipse also import their maven project). This will work, cause working directory when you run tests via IDE is the same as your project.
    • 3.1 When tests are going to be run via maven or
    • 3.2 via IDE, and more than one projects are imported into IDE (when you are not a student, you usually import several projects), AND before you run tests via IDE, you manually configure working directory for your tests. That working directory should refer to your imported project that contains the tests. By default, working directory of all projects imported into IDE is only one. Probably it is a restriction of IntelliJ IDEA only, but I think all IDEs work like this. And this configuration that must be done manually, is not good at all. Working with several tests existing in different maven projects, but imported into one big “IDE” project, force us to remember this and don’t allow to relax and get pleasure from your work.

    Solution offered by @ashosborne1 (personally I prefer this one) requires 2 additional requirements that must be done before you run tests. Here is a list of steps to use this solution:

    • Create a test folder (“teva”) and file (“readme”) inside of “src/test/resources/”:

      src/test/resources/teva/readme

      File must be created in the test folder, otherwise, it will not work. Maven ignores empty folders.

    • At least once build project via mvn clean install. It will run tests also. It may be enough to run only your test class/method via maven without building a whole project. As a result your test resources will be copied into test-classes, here is a path: target/test-classes/teva/readme

    • After that, you can access the folder using code, already offered by @ashosborne1 (I'm sorry, that I could not edit this code inside of this list of items correctly):

    public static final String TEVA_FOLDER = "teva"; ... 
    URL tevaUrl = YourTest.class.getClassLoader().getResource(TEVA_FOLDER); 
    String tevaTestFolder = new File(tevaUrl.toURI()).getAbsolutePath();
    

    Now you can run your test via IDE as many times as you want. Until you run mvn clean. It will drop the target folder.

    Creating file inside a test folder and running maven first time, before you run tests via IDE are needed steps. Without these steps, if you just in your IDE create test resources, then write test and run it via IDE only, you'll get an error. Running tests via mvn copies test resources into target/test-classes/teva/readme and they become accessible for a classloader.

    You may ask, why do I need import more than one maven project in IDE and why so many complicated things? For me, one of the main motivation: keeping IDA-related files far from code. I first create a new project in my IDE. It is a fake project, that is just a holder of IDE-related files. Then, I import already existing maven projects. I force these imported projects to keep IDEA files in my original fake project only. As a result I don't see IDE-related files among the code. SVN should not see them (don't offer to configure svn/git to ignore such files, please). Also it is just very convenient.

    0 讨论(0)
  • 2020-11-28 02:16

    Use .getAbsolutePath() on your File object.

    getClass().getResource("somefile").getFile().getAbsolutePath()
    
    0 讨论(0)
提交回复
热议问题