0

我有一个类似于的 Groovy 类

class MyClass {

  Foo foo
}

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

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

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

  1. 繁琐而冗长,尤其是如果 Foo 有很多方法
  2. 这将消除对 Foo 的任何实例的调用(不仅仅是 foo)

尽管 Groovy 提供了一个 StubFor 类,但如果我这样做:

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

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

def foo

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

谢谢,唐

4

4 回答 4

0

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

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

于 2009-06-10T18:25:25.253 回答
0

我猜这仅用于测试目的。

该行:

Foo foo

创建一个 getter / setter 对,因此您可以通过执行以下操作在测试用例中注入一个模拟:

new MyClass().foo = new MockFoo()

如果您不想为自己创建模拟,请尝试模拟库。我建议使用mockito。使用这个小型库,您可以执行以下操作:

import static org.mockito.Mockito.*;
new MyClass().foo = mock(Foo.class);
于 2009-06-10T18:42:15.390 回答
0

我找到了解决方案:

this.foo = {Object[] args -> println "I don't do anything"} as Foo
于 2009-06-10T19:21:30.880 回答
0

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

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

如果您存根一个类(如上面的 ArrayList 示例中),那么您未覆盖的方法将保留,因为它们在该类中实现。显然,您也可以存根接口。

如果您需要模拟功能(即验证测试中的行为,例如计算对给定方法的调用次数),我强烈建议您查看Spock 测试框架。它对更高级的 stubbing 和 mocking 有很好的支持。

于 2013-08-09T19:39:36.643 回答