本文介紹了Java模塊:Mockito 2.20.0的可訪問性問題的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!
問題描述
我正在從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
編譯器/Surefire都需要ASM 6.2,因為這些插件使用的ASM版本存在錯誤。
moockito-core 2.20.0(但之前在Java 8中使用2.20.0)。
日食光子R
該項目可以在這里找到ide-bugs.zip(它位于Eclipse論壇,因為我為另一個問題Topic on Eclipse制作了這個Topic on Eclipse,這一次是因為Eclipse的模塊有本地錯誤)。
測試非常簡單:我們嘗試用不同的訪問級別模擬不同的類–所有這些都在Java 8中工作。
-
包保護類
公共類,但未導出,未打開
公共類未導出,但向Mockito開放
公共類未導出,但向所有人開放
包保護類未導出,但對Mockito打開
包保護類未導出,但向所有人開放
在Java 8中,情況1、5和6是相同的(包的訪問受保護)。案例2、3和4相同(公共訪問權限)。
測試失敗,因為Mockito既不能:
類org.mockito.codegen.NotExportedOpenToMockitoProtected$MockitoMock$117073031無法訪問其超類nodatafound.mjpmsuc.withopens.NotExportedOpenToMockitoProtected
類org.mockito.codegen.NotExportedNotOpenedPublic$MockitoMock$365628885(在未命名模塊@0x3f07b12c中)無法訪問類nodatafound.mjpmsuc.internal.NotExportedNotOpenedPublic(在模塊nodatafound.moockito_jpms_usecase中),因為模塊nodatafound.moockito_jpms_usecase不會將nodatafound.mjpmsu.Internal導出到未命名模塊@0x3f07b12c
Mockito實際上有一個自動模塊名,但被視為未命名模塊,因為所有JAR都在類路徑中找到一個大的”未命名模塊”。
雖然我可以從包保護包遷移到非導出包,但我無法理解如何解決使我的接口/類對其他模塊不可見的問題?
[編輯]一個月后更新了插件/依賴項的版本,但沒有結果。
推薦答案
我在這里找到了問題的部分答案: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中為每個包指定它。
這會給surefire配置增加額外的負擔,而我更喜歡簡單的配置。
您沒有來自IDE的驗證;Eclipse將驗證模塊-info.java,標記為無效的包。
M2E未將必要的<argLine />
傳遞給Eclipse JUnit插件,導致在Eclipse中測試失敗。
maven方法(據我所知在Eclipse中也是如此,可能在Gradle中也是如此)不允許為測試添加額外的模塊信息;例如:讓測試依賴是模塊化的(這可能是使用每個源模塊的專用測試模塊來完成的,就像Eclipse對插件測試所做的那樣)。
這篇關于Java模塊:Mockito 2.20.0的可訪問性問題的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,