Использование JUnit 5 для одинаковой обработки тестовых файлов ресурсов как в IDE, так и в сборке Gradle - PullRequest
0 голосов
/ 04 марта 2020

Я пишу инструмент командной строки, который генерирует текстовые файлы. Я хочу написать тест JUnit 5, который сравнивает сгенерированный файл с ресурсом теста.

Чтобы тесты не «загрязняли» файловую систему, я использую пакет Google Jimfs, т.е. перед каждым тестом я настраиваю файловую систему с помощью

  fileSystem = Jimfs.newFileSystem(Configuration.unix()); 

Средство командной строки написано так, что он использует эту файловую систему во время теста и «нормальную» файловую систему во время нормального выполнения. Это отлично работает.

Когда я запускаю JUnit 5 в IDE (Eclipse 2019-03), кажется, что файл тестового ресурса находится как «обычный файл», так что в моем тестовом коде я могу использовать Java 8 NIO пакет для чтения файла, .eg:

Path p = = fileSystem.getPath("...");
// Now read the file in using the Path p 

Это отлично работает. Однако, когда я использую Gradle для создания исполняемого JAR-файла, файл ресурса теперь рассматривается как правильный ресурс, и код должен прочитать его, используя что-то вроде:

URI uri = ClassLoader.getSystemResource(resourceFileName).toURI();
// Now read the file in using the URI. 

Это означает, что у меня либо есть два набора тестового кода, один для запуска в Eclipse и один для запуска в Gradle (не совсем правильное решение) или - как я уже сделал - написал следующую утилиту:

  private Path getResourcePath(String resourceFileName) throws URISyntaxException, IOException {
       Path resourcePath;
       URI uri = ClassLoader.getSystemResource(resourceFileName).toURI();

       // Now check if the system resource is either a normal file (e.g. we are running in an IDE) or
       // the system resource is is a packaged JAR (e.g. we are running a packaged JAR file) 
       if (uri.getScheme().equalsIgnoreCase("jar")) {
           // Running as a packaged JAR so set up a file system to read this jar using the first 
           // part of the URI (separated with '!') as the file to use
           String[] uriParts = uri.toString().split("!");

           try {
               jarFileSystem = FileSystems.getFileSystem(URI.create(uriParts[0]));
           }
           catch(FileSystemNotFoundException e) {
               jarFileSystem = FileSystems.newFileSystem(URI.create(uriParts[0]), new HashMap<>());
           }
           resourcePath = jarFileSystem.getPath(uriParts[1]);
       } else {
           // Assume that the system resource is a normal file (e.g. we are running in an IDE). 
           String pathName = uri.getSchemeSpecificPart();
           // If there is a leading '/' then remove it if we run on Windows so we have a correct path specification.
           // TODO is there some way to remove this "special" case. 
           if (runsOnWindows() && pathName.startsWith("/")) {
               pathName = pathName.substring(1);
           }
           // The resource file is in the default file system and not any file system
           // that is being used for e.g. test. Returned path should therefore be 
           // associated with the default file system. 
           FileSystem fs = FileSystems.getDefault();
           resourcePath = fs.getPath(pathName);  
       }
       return resourcePath;
   }

Кажется, это работает. Однако, это все еще не кажется мне лучшим решением. Есть ли способ избавить меня от необходимости писать этот неуклюжий код? Может быть, что-то в Eclipse или JUnit 5 или Gradle или ... что-то еще? Или я что-то упустил абсолютно базовый c?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...