【发布时间】:2012-08-21 07:10:19
【问题描述】:
对于一个研究项目,我试图弄清楚单元测试(用 JUnit 编写)在不同上下文中执行时是否表现不同。为此,我做了两件事:首先,我使用自定义 JUnit Runner 运行程序的整个测试套件,然后使用相同的自定义 JUnit runner 运行单个测试(为什么这有意义并不重要,只需接受它现在)。当测试失败时,我会记录 JUnit 报告的整个异常堆栈跟踪,然后比较两次运行之间的堆栈跟踪。
这样做时,我偶然发现了一些我无法解释的奇怪事情。以下是以这种方式记录的两个堆栈跟踪的两个摘录。
运行整个测试套件时记录的堆栈跟踪:
org.fest.swing.edt.GuiActionRunner.resultOf(GuiActionRunner.java:126)
org.fest.swing.edt.GuiActionRunner.execute(GuiActionRunner.java:73)
net.sourceforge.squirrel_sql.fw.datasetviewer.cellcomponent.AbstractNumericDataTypeUITest.constructTestFrameInEDT(AbstractNumericDataTypeUITest.java:98)
net.sourceforge.squirrel_sql.fw.datasetviewer.cellcomponent.AbstractNumericDataTypeUITest.setUp(AbstractNumericDataTypeUITest.java:81)
sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source) - sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:616)
org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
运行单个测试时记录的堆栈跟踪:
org.fest.swing.edt.GuiActionRunner.resultOf(GuiActionRunner.java:126)
org.fest.swing.edt.GuiActionRunner.execute(GuiActionRunner.java:73)
net.sourceforge.squirrel_sql.fw.datasetviewer.cellcomponent.AbstractNumericDataTypeUITest.constructTestFrameInEDT(AbstractNumericDataTypeUITest.java:98)
net.sourceforge.squirrel_sql.fw.datasetviewer.cellcomponent.AbstractNumericDataTypeUITest.setUp(AbstractNumericDataTypeUITest.java:81)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:616)
org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
两个堆栈跟踪都显示崩溃前的最后几个条目,从最后一个通用语句开始。显然,在 JDK/VM 的反射实现中的某处,这两种情况的行为有所不同。
我的问题是为什么?
我推测这与早期反射调用中的 VM 缓存内容有关,但我真的不知道。了解这一点很重要,因为我必须弄清楚这是否会发生每次我运行一个测试(因此我可以忽略它),或者这是否与我正在运行的特定测试。
我知道这很模糊,但我们将不胜感激。
【问题讨论】:
-
“我推测这与早期反射调用中的 VM 缓存内容有关”:不太可能 - 可能是由于在测试框架。推论:这应该是从一次运行到另一次运行的一致行为。
-
运行之间肯定是一致的。如果我有一种简单的方法来检查在没有抛出异常的情况下是否发生同样的事情,我会很高兴。但是使用仪器来解决这个问题可能有点矫枉过正。
-
你有没有检查堆栈跟踪中每个项目对应的源代码以尝试遵循执行路径?
-
不,因为差异在于 JDK,而我没有运行它的 JDK 的源代码。
-
谷歌:
sun.reflect.DelegatingMethodAccessorImpl .java=> grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/…
标签: java reflection junit