假设我有一个接口,其中包含许多我想要为测试进行模拟的方法,并且假设我不需要它来做任何事情,我只需要测试中的对象来获得它的实例。例如,我想在一些代码上运行一些性能测试/基准测试,并且不希望这个接口上的方法有所贡献。
有很多工具可以轻松完成,例如
Interface mock = Mockito.mock(Interface.class);
ObjectUnderTest obj = ...
obj.setItem(mock);
或其他什么。
但是,它们都带来了一些我宁愿避免的运行时开销:
(我愿意纠正这些例子的任何细节,但我相信这个原则是有效的。)
我的目标是接口的“真正的”无操作实现,例如我可以手动编写返回null
,false
或0
的所有内容。但如果我感到懒惰并且界面有很多方法,那就无济于事。那么,如何在运行时生成并实例化任意接口的这种无操作实现呢?
有一些工具可供使用,例如Powermock,CGLib,它们使用字节码生成,但仅作为较大的模拟/代理上下文的一部分,我还没有想出从内部选择的内容。
好的,所以这个例子可能有点做作,我怀疑代理会对时间产生太大影响,但我现在很好奇如何生成这样一个类。 CGLib,ASM是否容易?答案 0 :(得分:3)
不确定这是否是您正在寻找的,但Eclipse中的“新类”向导允许您构建新类并指定超类和/或接口。如果你允许它,它将自动编码所有接口/抽象方法的虚拟实现(返回null
除非void
)。这样做非常轻松。
我怀疑其他“大牌”IDE,例如NetBeans和Idea,都有类似的功能。
编辑:
再次查看您的问题,我想知道为什么在处理测试类时您会担心自动代理的性能。在我看来,如果性能是一个问题,你应该测试“真正的”功能,如果你正在处理大多数未实现的类,那么你不应该处于性能重要的测试环境中。
答案 1 :(得分:0)
构建实用程序需要一些工作,但对于没有“边缘情况”(注释等)的基本vanilla Java接口可能不会太难,使用Javassist代码生成在运行时以文本方式创建实现null的类在接口上定义的每个方法的版本。这与Javassist ProxyFactory(或CGLib Enhancer)代理对象不同,后者仍然具有几层间接。我认为直接字节码生成模式在结果类中没有开销。如果你很勇敢,你也可以潜入ASM做同样的事情。