网站首页 > 技术教程 正文
如下所示,当我在进行单元测试时,控制台居然抛出了这么诡异的bug!
三个感叹号开头
此刻的我 ???
异常信息如下:
java.lang.ClassNotFoundException: junit.framework.ComparisonFailure
那么先挖到它的源码看个究竟吧
:stuck_out_tongue_closed_eyes:
在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失败时抛出
如下 ε=ε=ε=(
 ̄▽ ̄)
居然还有邮箱 :mailbox:
为何会出现 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{
@Test
public 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 看下了,无奈作罢 :pig2:
插曲
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 的版本~ :pig:
三. 扩展包解惑
比如我在 pom 文件中引入了这个 spring-boot-starter-test ,此时它会帮我导入 相应版本 的 junit 包 ,而我也不知道它引入了什么版本的测试包,这时可以在 IDEA 的扩展包中搜索
,就可以查找到 junit 的版本了
四. junit3 是使用继承的方式, Junit4 开始才使用注解的形式
所以,如果你想试试继承的写法的话,可以试试 哈哈
五. 单元测试很重要,主要是为了证明你的逻辑在这个测试范围是对的:stuck_out_tongue_closed_eyes:
原文链接:
https://juejin.cn/post/6961264708749885453
猜你喜欢
- 2025-03-12 这是台有味道的车!Suzuki 改了一台Jimny Beans专属咖啡车
- 2025-03-12 【心坎情话】一见倾心,再见倾情,我爱你,此生不渝。
- 2025-03-12 Burgeoning China-Africa Trade Enables African Coffee Beans to Arrive in China Faster
- 2025-03-12 每周六 “Berry Beans”精品手冲咖啡课程
- 2025-03-12 清甜软糯,Magic Beans--HiFiMAN RE300H
- 2025-03-12 《老友记》六人17年后重聚,罗斯和瑞秋坦言他们彼此动过心
- 2025-03-12 AWS Beanstalk搭建WordPress站点,如此简单!
- 2025-03-12 MIUI主题强力推荐:《夜幕》
- 2025-03-12 比呀比: BeanStalk 雪印 孕妇
- 2025-03-12 《Beans1980》上架安卓平台 春蚕与豆腐君的故事
你 发表评论:
欢迎- 最近发表
-
- 并发编程 - 线程同步(七)之互斥锁Monitor
- Marshall Monitor Bluetooth视频评测
- 自管理网络(SON)策略和优化功能介绍
- 拒绝大块头和全家桶 个性监控小软件了解下
- 意大利 zingail(号令)MONITOR 112-II 现场聆听(什么是恋爱)
- 猛牌Monitor Audio Silver 300 7G 落地音箱详细评测
- 索尼Monitor&Control V2.0.0应用更新,带来多机监控等功能
- 由三个感叹号开启的 Debug 篇章?
- 这是台有味道的车!Suzuki 改了一台Jimny Beans专属咖啡车
- 【心坎情话】一见倾心,再见倾情,我爱你,此生不渝。
- 标签列表
-
- sd分区 (65)
- raid5数据恢复 (81)
- 地址转换 (73)
- 手机存储卡根目录 (55)
- tcp端口 (74)
- project server (59)
- 双击ctrl (55)
- 鼠标 单击变双击 (67)
- debugview (59)
- 字符动画 (65)
- flushdns (57)
- ps复制快捷键 (57)
- 清除系统垃圾代码 (58)
- web服务器的架设 (67)
- 16进制转换 (69)
- xclient (55)
- ps源文件 (67)
- filezilla server (59)
- 句柄无效 (56)
- word页眉页脚设置 (59)
- ansys实例 (56)
- 6 1 3固件 (59)
- sqlserver2000挂起 (59)
- vm虚拟主机 (55)
- config (61)
本文暂时没有评论,来添加一个吧(●'◡'●)