Testing Grails:我如何模拟被测类的其他方法,这些方法可能在测试期间被内部调用

Testing Grails:我如何模拟被测类的其他方法,这些方法可能在测试期间被内部调用,testing,grails,groovy,mocking,tdd,Testing,Grails,Groovy,Mocking,Tdd,我正在一个类似于下面给出的服务类中为methodA()编写一个测试 Class SampleService { def methodA(){ methodB() } def methodB(){ } } 当我测试methodA()时,我需要能够在测试methodA()时模拟对methodB()的调用。我使用的是grails的2.0.x版本。在1.3.x发行版中,我会写一个这样的自嘲 def sampleServiceMock = mockFor(SampleServ

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

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

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

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

但这在2.0.x版本中不起作用。在测试methodA()时,我想知道还有哪些方法可以模拟methodB()

Groovy有很多模拟方法。您可以查看或的一些文档

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

void testMethodA() {
    service = new SampleService()
    service.metaClass.methodB = { -> return "what you want" }
    service.methodA()
    assert "your condition"
}

对于这类问题,我实际上避免了模拟,并使用内置的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()

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

我最终使用了这种方法来模拟。但是,从语义上讲,更改类的签名以使测试通过似乎是极端的:)链接(Groovy Mock,使用Maps和Expandos代替Mock,或使用闭包代替Mock)不再工作,请修复或删除它们。谢谢。是的,这似乎是嘲笑行为的好方法。我仍然怀念使用grails的mockFor()进行自模拟的能力:(非常棒。这帮助了我以及我在创建Spock闭包时进行的测试,并且无法断言从控制器返回的实际值(模拟服务调用时)。如果方法包含参数会怎么样。我正在尝试一个我一直得到的;
groovy.lang.MissingMethodException:没有方法的签名:…适用于参数类型:(java.lang.String,java.lang.String)
有人知道如何使用Spock为Grails 3.2.8这样做吗?