模拟 Swing 静态方法时出现 java.lang.VerifyError
我正在使用 PowerMock 模拟 JOptionPane
上的静态方法,但 JRE 似乎不太符合它,因为我在初始化时收到 java.lang.VerifyError
,因为它检查自己的包和类的完整性。
我有一些解决方法,但我对其中任何一个都不太满意:
为
JOptionPane
编写一个对象包装器,并为我需要的方法提供一个接口(showInputDialog
等),这样我就可以注入模拟或存根进行测试。这只是将问题转移到其他地方,因为我仍然需要覆盖我的包装器方法,但至少它们将与逻辑隔离。使用JOptionPane
的实例而不是类引用来调用其上的方法(我认为模拟实例不会有任何问题,因为该类不是最终的)。缺点是我会收到很多“在实例变量上调用静态方法”之类的警告,但这就是要付出的代价。根本不要模拟
JOptionPane
并使用Robot
触发输入事件来处理它。这可能非常麻烦而且不太健壮...除此之外,我正在使用内部对话框,这需要额外的工作来设置JDesktopPane
、JInternalFrame
等
还有其他想法或建议吗?
谢谢!
更新:顺便说一句,我尝试模拟 JOptionPane
实例,方法调度程序似乎忽略了实例,直接选择了以前存在的静态方法(这是有道理的,毕竟),所以第二个选项被丢弃。
I am using PowerMock to mock static methods on JOptionPane
, but the JRE doesn't seem to be very conform with it, because I get a java.lang.VerifyError
at initialisation, as it checks the integrity of its own packages and classes.
I have though of a few workarounds, but I'm not very happy with any of them:
Write an object wrapper for
JOptionPane
and provide an interface for the methods I need (showInputDialog
, etc.), so I can inject a mock or an stub for testing. This just moves the problem elsewhere, as I would still need to cover my wrapper methods, but at least they will be isolated from the logic.Use an instance ofJOptionPane
instead the class reference to call the methods upon it (I think I won't have any problems mocking an instance, as the class is not final). The downside is that I will get lots of warnings of the kind "invoking static method on an instance variable", but that's the price to pay.Do not mock
JOptionPane
at all and useRobot
to fire the input events to handle it. This can be very cumbersome and not very robust... Besides that, I am using internal dialogs, and that requires extra work to set up theJDesktopPane
,JInternalFrame
s and so on.
Any other ideas or suggestions?
Thanks!
update: by te way, I've tried mocking a JOptionPane
instance and it seems that the method dispatcher ignores the instance picks directly the previously existing static method (it makes sense, after all), so the second option is discarded.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
为
JOptionPane
编写一个包装器 - 这绝对是最强大的选项,并且还允许您自己编写方便的速记方法。我会选这个。如果像我和大多数其他开发人员一样,您的项目中已经有一些 GUI 帮助程序类,那么他们可以去那里。使用实例 - 不是一个糟糕的解决方案,但绝对不如调用单个静态方法那么容易管理。我不认为增加的复杂性是值得的。
使用
机器人
来模拟输入 - 是的,这对我来说听起来非常脆弱。此时您将变得依赖于 JOptionPane 的内部结构和实现细节,这不是一个好地方。JOptionPane
的行为和按钮顺序在不同的外观和感觉下也可能有所不同(即“确定”、“取消”与“取消”、“确定”)。最后,这在无头环境中不起作用(尽管如果您已经在测试中使用 JOptionPane,并且计划始终在桌面计算机上进行测试,那么这不是问题)。Write a wrapper for
JOptionPane
- this is definitely the most robust option, and also allows you to write convenient short-hand methods for yourself. I'd pick this one. If, like myself and most other developers, you already have some GUI helper class somewhere in your project, they can go there.Use an instance - not a bad solution, but definitely not as easy to manage as a call to a single static method. I wouldn't say the added complexity was worth it.
Use a
Robot
to mock the inputs - yes, that sounds extremely fragile to me. You become dependent on the internal structure and implementation details ofJOptionPane
at that point, which is not a good place to be.JOptionPane
s' behaviors and button order may also vary under different look-and-feels (i.e. OK, Cancel vs. Cancel, OK). Finally, this won't work in a headless environment (although if you're already usingJOptionPane
s in your tests, and plan on always testing on a desktop machine, that isn't a concern).