Groovy:存根类型引用

时间:2009-06-10 18:20:30

标签: groovy stubbing

我有一个类似于

的Groovy类
class MyClass {

  Foo foo
}

在某些情况下,我不想初始化foo,并希望将所有调用都删除。任何返回值的方法都不应该做任何事情。我可以这样做:

Foo.metaClass.method1 = {param -> }
Foo.metaClass.method2 = { -> }
Foo.metaClass.method3 = {param1, param2 -> }

虽然这会起作用,但它有几个问题

  1. 乏味且啰嗦,特别是如果Foo有很多方法
  2. 这将对任何Foo实例(不仅仅是foo)
  3. 进行调用

    虽然Groovy提供了StubFor类,但如果我这样做:

    this.foo = new groovy.mock.interceptor.StubFor(Foo)
    

    我在运行时获得了ClassCastException。虽然如果我可以将foo重新定义为:

    ,这将起作用
    def foo
    

    但由于我不会进入这里的原因,我不能这样做。

    谢谢, 唐

4 个答案:

答案 0 :(得分:0)

您需要将Foo实例传递给MyClass对象。在测试中,传入存根实现。在真正的程序中传递一个真正的实现。

您不需要任何特殊的框架来编写存根。如果您只是将查询存根到Foo并且对期望命令不感兴趣,那么手动编写存根实现会更容易。模拟对象库是过度的,并且会使后来的代码读者感到困惑,他们希望测试包含期望。

答案 1 :(得分:0)

我猜这只是出于测试目的。

该行:

Foo foo

创建一个getter / setter对,这样你就可以通过这样做在你的测试用例中注入一个mock:

new MyClass().foo = new MockFoo()

如果您不想为自己创建模拟,请尝试使用模拟库。我建议使用mockito。有了这个小型库,您可以这样做:

import static org.mockito.Mockito.*;
new MyClass().foo = mock(Foo.class);

答案 2 :(得分:0)

我找到了解决方案:

this.foo = {Object[] args -> println "I don't do anything"} as Foo

答案 3 :(得分:0)

您也可以使用地图创建存根,从而可以存储多个方法,如下所示:

def stubbedList = [empty : { false }, get: {index -> "always return this"}] as ArrayList

如果您存根一个类(如上面的ArrayList示例中所示),那么您不会覆盖的方法将保留在类中实现。你也可以明显地存在接口。

如果您需要模拟功能(即验证测试中的行为,例如计算给定方法的调用次数),我强烈建议您查看Spock test framework。它非常支持更高级的存根和嘲弄。