Модули Java: проблемы доступности для Mockito 2.20.0 - PullRequest
0 голосов
/ 01 июня 2018

Я перехожу с Java 8 на Java 10 и запускаю тест, который сейчас не проходит из-за классов, защищенных пакетами.Сборка выполняется под maven 3.5.4 + Oracle JDK 10.0.2:

  • maven-compiler-plugin 3.7.0 + asm 6.2
  • maven-surefire-plugin 2.22.0+ asm 6.2 + junit 5.2.0
  • asm 6.2 требуется для обоих компиляторов / верных из-за ошибки в версии ASM, используемой этими плагинами.
  • mockito-core 2.20.0 (но использовал 2.20.0 с Java 8 раньше).
  • Eclipse Photon R

Проект можно найти здесь ide-bugs.zip (этонаходится на форуме Eclipse, потому что я создал эту тему на Eclipse для другой проблемы, на этот раз с Eclipse, имеющей локальную ошибку с модулем).

Тест очень прост: мы пытаемся смоделироватьдругой класс, с разным уровнем доступа - все они работали в Java 8.

  1. защищенный пакет класс
  2. открытый класс, но не экспортированный, не открытый
  3. открытыйкласс не экспортируется, но открывается для Mockito
  4. открытый класс не экспортируется, но открывается для всех
  5. pЗащищенный класс ackage не экспортируется, но открывается в Mockito
  6. Защищенный класс пакета не экспортируется, но открывается для всех

В Java 8 случаи 1, 5 и 6 одинаковы (доступ к пакетузащищенный).Случаи 2, 3 и 4 одинаковы (доступ к общедоступным).

Тест не пройден, так как Mockito не может:

  • class org.mockito.codegen.NotExportedOpenToMockitoProtected $ MockitoMock$ 117073031 не может получить доступ к своему суперклассу nodatafound.mjpmsuc.withopens.NotExportedOpenToMockitoProtected
  • , класс org.mockito.codegen.NotExportedNotOpenedPublic $ MockitoMock $ 365628885 (в именованном модуле nodpound..mockito_jpms_usecase), поскольку модуль nodatafound.mockito_jpms_usecase не экспортирует nodatafound.mjpmsuc.internal в неназванный модуль @ 0x3f07b12c

. У Mockito фактически есть имя Automatic-Module-Name, но оно рассматривается как неиспользованный модуль, поскольку найден весь jar-файлв пути к классам для большого «неназванного модуля».

Хотя я в порядке с переходом от защищенного пакета к неэкспортированному пакету, я не понимаю, как решить проблему с сохранением моего интерфейса/ класс не виден другим модулям?

[править] обновил версию плагина / зависимости через месяц, безрезультатно.

1 Ответ

0 голосов
/ 25 июля 2018

Я нашел часть ответа на мою проблему здесь: https://blog.codefx.org/java/java-module-system-tutorial/#Open-Packages-And-Modules

  • Mockito использует отражение для доступа к классам из модуля или пути к классам.
  • Mockito находится в«безымянный модуль», потому что Maven добавляет его в путь к классу, а не в путь к модулю.Это объясняет, почему opens package to org.mockito никогда не работает: отсутствует модуль org.mockito.
  • Maven Surefire не хочет вносить вклад в «открытия» модуля, чтобы разрешить Mockito доступ к нему.
  • Mockito (больше не?) Способен макетировать не частные и не финальные классы .Любые средства защищенного пакета являются частными.Ошибка довольно явная: Mockito создает класс, расширяющий защищенный класс пакета, который теперь не работает (раньше он работал, но, вероятно, это произошло из-за того, что Mockito создал класс в том же пакете, что и тот, который подвергается насмешке).

Тем не менее, это приводит к проблемной конфигурации в pom.xml каждого модуля:

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <configuration>
          <argLine>    
  --add-opens nodatafound.mockito_jpms_usecase/nodatafound.mjpmsuc=ALL-UNNAMED
        </configuration>      
      </plugin>

Нам нужно явно добавить открытий в неназванный модуль .Это не должно быть сделано в module-info.java, потому что он открывает для модуля всех других модулей или jar-файлов, что противоречит инкапсуляции.

Это проблематично, потому что:

  • Вам нужно указать его в pom.xml для каждого пакета.
  • Это добавляет дополнительную нагрузку к верной конфигурации, которую я предпочитаю простой.
  • У вас нет подтверждения отIDE;Eclipse проверит module-info.java, помечая неверный пакет.
  • m2e не передает плагину Eclipse JUnit необходимое <argLine />, что делает тест неудачным в Eclipse.

Подход maven (такой же в Eclipse и, возможно, Gradle какнасколько я знаю) не разрешает дополнительный модуль-info для тестов;Например: позволяет тестовой зависимости быть модульной (возможно, это можно сделать с помощью выделенного тестового модуля для каждого исходного модуля, как это делает Eclipse для тестов плагинов).

...