!!! JUnit version 3.8 or later expected
小伙伴們好呀,沖沖沖!!😝
本期帶來了一個奇怪的bug~和它帶來的一系列問題,讓我們一起往下看看叭!
!!! JUnit version 3.8 or later expected:
如下所示,當我在進行單元測試時,控制臺居然拋出了這么詭異的bug!
三個感嘆號開頭
此刻的我 ???
異常信息如下:
java.lang.ClassNotFoundException: junit.framework.ComparisonFailure
那么先挖到它的源碼看個究竟叭 😝
在264行打個斷點,然后debug運行起來
通過 Alt+F8 來獲取這個類加載器 都使用到了哪些類
ClassLoader.getClassLoader(caller)
效果如下:可以看到這里
至于為啥會點開這里,主要時因為它比較突出 哈哈~
可以發現它加載了idea 插件目錄 IntelliJ IDEA 2020.1\plugins\junit\lib 中的 junit-rt.jar 文件
猶豫了下,還是繼續探究下去 哈哈
奇怪的參數
于是我就一路 debug 下來,最后看到這個東東, 運行了 JUnitStarter 的 main 函數~
同時傳遞了三個變量
- -ideVersion5
- -junit3
- com.java4ye.demo.A,contextLoads (類,測試方法)
如圖~
這里我們把這個 junit-rt.jar 解壓到上面的這個 junit-rt 目錄,
用 IDEA 打開 很快就可以找到這個 JUnitStarter 了。
!!!的來源
查閱代碼,發下有這么一個調用邏輯~
if (!"com.intellij.junit5.JUnit5IdeaTestRunner".equals(agentName) && !canWorkWithJUnitVersion(System.err, agentName)) {System.exit(-3); }Soga , 這個 Process finished with exit code -3 是這么來的
canWorkWithJUnitVersion
junitVersionChecks
小結
可以發現如果代理名稱 agentName 不是 com.intellij.junit5.JUnit5IdeaTestRunner
就會去 check 這個 junit 版本。 然后去加載這個 junit.framework.ComparisonFailure 類。
tip:Junit5 中并沒有這個類,版本 5 的架構更復雜,JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage
順帶提下這個 ComparisonFailure 的作用:
當斷言equals for Strings失敗時拋出
如下 ε=ε=ε=( ̄▽ ̄) 居然還有郵箱 📫
為何會出現 Junit3 這個奇怪的參數
這里先解釋下,傳遞的參數乎關系到這個 agentName
那么問題來了!
在我的 demo 中,使用的 Springboot 版本是 2.4.5 ,同時在 pom 文件中引入了 spring-boot-starter-test ,它的版本號是5.7 ,如下
可以看到明明使用的是 JUnit5 呀
帶著疑問來看看項目的結構是啥樣子叭~
嘿嘿,可以發現這里 test 目錄下 和 main 目錄中有個 同包同名的類 A
test 下的 A
package com.java4ye.demo;//import org.junit.Test;import org.junit.jupiter.api.Test;public class A{@Testpublic void contextLoads() {System.out.println("hello");}}這時我嘗試著將這個 test 下的 A 重命名為 AA ,奇怪的是,它正常跑起來了,哈哈,而且確實是用的 Junit5
于是我又做了一個實驗,導入 Junit4 的包,將 AA 改為 A ,繼續測試,結果也是正常的
小結
使用 Junit5 時,如果測試目錄 test 下的測試類和 main 目錄下的同包同名,會出現這個奇怪的參數 -Junit3 , 導致拋出異常 !!! JUnit version 3.8 or later expected:
這里我也很好奇為啥參數變成了 -Junit3 ,可是不懂要怎么 debug 看下了,無奈作罷 🐖
插曲
java.lang.NoClassDefFoundError:
在找到這個 JUnitStarter 類時, 4ye 嘗試著用命令 java JUnitStarter 去運行,結果居然拋出了 java.lang.NoClassDefFoundError:
java JUnitStarter 命令去運行,結果居然拋出了 java.lang.NoClassDefFoundError:
區別
不知道小伙伴們對這個 Error 熟不熟悉 哈哈,平時看到的都是 ClassNotFoundException
這兩者最大的區別就是:
一個是 Error ,一個是 Exception 哈哈
詳細點點說:
ClassNotFoundException 是非運行時異常,在編譯期間就檢測出來可能會發生的異常,需要你 try catch 的
而這個 java.lang.NoClassDefFoundError: 是屬于 error ,是 JVM 處理不了的錯誤。
這里還有一點點小細節~
就是這個原因是在 JDK11 下才顯示出來的,之前用 JDK8 只有錯誤一行~ 小伙伴們可以自己嘗試下
解決辦法
咳咳,那這個 錯誤 怎么解決呢 ?
其實這個也是最原始的解決辦法 哈哈
可以在上面 IDEA 中反編譯出來的代碼看到我們這個 JUnitStarter 是屬于
package com.intellij.rt.junit; 包的 。
那么我們正確的運行方式就是跑到 com 的同級目錄下去運行 ,如下~
注意這里運行時要帶上包名(先不帶上那三個參數試試~)
java com.intellij.rt.junit.JUnitStarter可以看到這里已經出現了 !!! JUnit version 3.8 or later expected
也就是我們文章最開始的那段異常信息了!
后面手動將需要的包放到這個目錄下,也可以正常運行啦~
其他小實驗和感悟就寫在下面的總結里啦~
總結
一. 單元測試的命名要規范!
二. 不要引入不同版本的單元測試包
如果項目中使用到這個 Junit5 ,此時又直接根據上面 !!! JUnit version 3.8 or later expected 這個異常,引入 Junit4 , 會出現新的異常
java.lang.Exception: No runnable methods ,此時需要你將 @Test 注解修改為 junit4 的版本~ 🐷
三. 擴展包解惑
比如我在 pom 文件中引入了這個 spring-boot-starter-test ,此時它會幫我導入相應版本的 junit 包 ,而我也不知道它引入了什么版本的測試包,這時可以在 IDEA 的擴展包中搜索~,就可以查找到 junit 的版本了~
四. junit3 是使用繼承的方式, Junit4 開始才使用注解的形式
所以,如果你想試試繼承的寫法的話?,可以試試 哈哈
五. 單元測試很重要,主要是為了證明你的邏輯在這個測試范圍是對的😝
我是4ye,我們下期再見啦,ヾ( ̄▽ ̄)ByeBye
歡迎關注,交個朋友呀!! ( ?? ω ?? )y
作者簡介 :Java4ye ,很高興認識你!!😝
公眾號: Java4ye 博主滴個人公眾號~ ,嘿嘿 喜歡就支持下啦 😋
讓我們開始這一場意外的相遇吧!~
歡迎留言!謝謝支持!ヾ(≧▽≦*)o
總結
以上是生活随笔為你收集整理的!!! JUnit version 3.8 or later expected的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 怎么用python破解wifi密码?
- 下一篇: python爬取qq空间说说