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。

如何修补与被测类在同一文件中的类,即在测试开始之前初始化?

如何通过反射访问一个类的私有方法

如何通过反射访问一个类的私有方法

如何在 Grails 单元测试中使用 Spock 模拟 passwordEncoder

更新gradle后Android单元测试无法解析被测类