20

我正在为类似于下面给出的服务类中的 methodA() 编写测试。

Class SampleService {
  def methodA(){
     methodB()
  }

  def methodB(){
  }
}

当我测试 methodA() 时,我需要能够在测试 methodA() 时模拟对 methodB() 的调用。我正在使用 2.0.x 版的 grails。在 1.3.x 发行版中,我会像这样编写一个自我模拟

def sampleServiceMock = mockFor(SampleService) 
sampleServiceMock.demand.methodB { -> } 

但这在 2.0.x 版本中不起作用。我想知道在测试 methodA() 时模拟 methodB() 的其他方法是什么

4

2 回答 2

37

对于这类问题,我实际上避免使用模拟并使用内置的 groovyProxy 功能将闭包映射转换为代理对象。这为您提供了一个实例,其中一些方法被覆盖,但其他方法被传递给了真正的类:

class SampleService {
    def methodA() {
        methodB()
    }

    def methodB() {
        return "real method"
    }
}

def mock = [methodB: {-> return "mock!" }] as SampleService

assert "mock!" == mock.methodA()
assert "real method" == new SampleService().methodA()

我喜欢只更改一个实例,可以在一行中完成,并且不会弄乱该实例之外需要清理的任何东西的元类。

于 2012-04-18T13:52:52.043 回答
13

Groovy 有很多模拟替代方案。您可以查看Groovy Mocks 的一些文档,使用 Maps 和 Expandos 代替 Mocks使用 Closures 代替 Mocks

在您的示例中,我将使用 Groovy 的元编程功能。

void testMethodA() {
    service = new SampleService()
    service.metaClass.methodB = { -> return "what you want" }
    service.methodA()
    assert "your condition"
}
于 2012-04-18T08:25:40.063 回答