Grails:我如何模拟被测类的其他方法,这些方法可能在测试期间被内部调用
Posted
技术标签:
【中文标题】Grails:我如何模拟被测类的其他方法,这些方法可能在测试期间被内部调用【英文标题】:Grails : How I do mock other methods of a class under test which might be called internally during testing 【发布时间】:2012-04-29 12:54:33 【问题描述】:我正在为类似于下面给出的服务类中的 methodA() 编写测试。
Class SampleService
def methodA()
methodB()
def methodB()
当我测试 methodA() 时,我需要能够在测试 methodA() 时模拟对 methodB() 的调用。我正在使用 2.0.x 版的 grails。在 1.3.x 发行版中,我会像这样编写一个 self mock
def sampleServiceMock = mockFor(SampleService)
sampleServiceMock.demand.methodB ->
但这在 2.0.x 版本中不起作用。我想知道在测试 methodA() 时模拟 methodB() 的其他方法是什么
【问题讨论】:
有人知道如何使用 Spock 为 Grails 3.2.8 执行此操作吗? 【参考方案1】:对于这类问题,我实际上避免使用模拟并使用内置的 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()
我喜欢只更改一个实例,可以在一行中完成,并且不会与该实例之外需要清理的任何东西的元类混淆。
【讨论】:
是的,这似乎是一种嘲弄行为的好方法。我仍然怀念使用 grails 的 mockFor() 进行自我模拟的能力 :( 太棒了。这有助于我以及我创建 Spock 闭包的测试,并且无法断言从控制器返回的实际值(在模拟服务调用时)。 如果方法接受参数怎么办。我正在尝试不断获得;groovy.lang.MissingMethodException: No signature of method: ... is applicable for argument types: (java.lang.String, java.lang.String)
【参考方案2】:
Groovy 有很多模拟选项。您可以查看Groovy Mocks、using Maps and Expandos instead of Mocks 或using Closures instead of Mocks 的一些文档。
在您的示例中,我将使用 Groovy 的元编程功能。
void testMethodA()
service = new SampleService()
service.metaClass.methodB = -> return "what you want"
service.methodA()
assert "your condition"
【讨论】:
我终于用这种方法来模拟了。但是,从语义上讲,更改类的签名以使测试通过似乎是极端的:) 链接(Groovy Mocks,使用 Maps 和 Expandos 代替 Mocks 或使用 Closures 代替 Mocks)不再有效,请修复或删除它们。谢谢。以上是关于Grails:我如何模拟被测类的其他方法,这些方法可能在测试期间被内部调用的主要内容,如果未能解决你的问题,请参考以下文章
python中suite.addTest没有执行测试用例,求大神指教,附件分别是main文件与被测类login与logout。