使用 ASM 字节码进行测试
假设我正在检测一个类,我想在其中向方法的某些部分添加一些指令。例如,让我们考虑这样的情况:我想要开发一个访问者 V
将方法 Cm()
中存在的方法调用指令从 Cn()
重命名到C.n_detour()
。
测试在 C
上运行 V
后是否确实能获得所需结果的最简单方法是什么?我在这里讨论的是 xUnit 风格的测试。
起初我以为我可以通过 C
运行 TraceMethodVisitor
,并将其与我自己的字符串进行比较,但结果发现有很多“装饰”指令(例如行编号等),这些与我的测试很大程度上无关(请参阅 格式化TraceClassVisitor 的输出)。
理论上,我知道我可以让一些访问者运行并检查 C.n_detour()
是否存在以及 Cn()
是否存在,但我宁愿使用与上述方法类似的东西(比较每条指令的指令)。
我查看了 ASM 的 Tree API,但看起来并没有那么好,因为那些 decoration
指令也出现在那里。
有人有过使用 ASM 测试代码的经验吗?
Let's say I am instrumenting a class, in which I want to add a couple of instructions to some parts of a method. For instance, let's consider the case where I want develop a visitor V
to rename method call instructions existent in method C.m()
from C.n()
to C.n_detour()
.
What would be the easiest way to test that after running V
over C
, one would indeed get the desired results? I'm talking about xUnit style testing here.
At first I thought I could run TraceMethodVisitor
over C
, and compare it to a string of my own, but it turned out that there is a lot of "decoration" instructions (such as line numbering, etc) that are largely irrelevant to my tests (see Formatting the output of a TraceClassVisitor).
Theoretically I know I could make some visitor that'd run and check both the existence of a C.n_detour()
and the non-existence of C.n()
, but I'd rather use something more along the lines of the above approach (comparing instruction per instruction).
I took a look at ASM's Tree API, but it doesn't look that much better, as those decoration
instructions show up there, too.
Does anyone have experience in the past testing code using ASM?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
保护
C.n_detour()
,在测试用例中扩展C
并计算调用次数。模式:您的所有检测都会产生一些新的副作用 - 这就是您首先进行检测的原因 - 因此编写测试来检查是否存在副作用。不要测试仪器的特定实现,而是测试一般的“它是否具有预期的效果”。
可能需要一个新的类加载器将
C
的检测版本放在类路径上。如果您使用 Maven,我建议插入一个模块并将测试放入第二个模块中。
Make
C.n_detour()
protected, extendC
in a test case and count the number of invocations.Pattern: All your instrumentations will create some new side effect - that's why you're instrumenting in the first place - so write tests which check whether side effect is there or not. Don't test for a specific implementation of the instrumentation but for the general "does it have the desired effect".
Might need a new classloader to put the instrumented version of
C
on the classpath.If you use Maven, I suggest to instrument in one module and put the tests into a second module.