Groovy每个实例的metaClass方法重写无法在Spock测试中按预期工作 [英] Groovy per instance metaClass method override doesn't work as expected in Spock test

查看:211
本文介绍了Groovy每个实例的metaClass方法重写无法在Spock测试中按预期工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有名为execute()的方法的类.在一些Spock单元测试中,我虚拟出execute方法,并给它一个模拟闭包,如下所示:

I have a class with method called execute(). In some Spock unit test I dummy out the execute method and give it a mock closure like this:

def setup () {
    rule = new DynamicRule ()
}

def "test default execution " (){
    given : "basic AORule "
    def mockres
    rule.metaClass.execute = {-> mockres = "did nothing"}     //mock the action
    def res = rule.execute()


    expect : "execute should do nothing "
    mockres == "did nothing"

}

如果我运行此测试,它将失败.在想法编辑器中,它以下划线显示了模拟关闭,但是下一行的rule.execute()不是-因此可以看到该方法.

If I run this test it fails. In the idea editor it shows the mock closure as underlined, but the rule.execute() on the next line isn't - so it can see the method.

如果我为此更改测试:

    rule.metaClass.execute2 = {-> mockres = "did nothing"}     //mock the action
    def res = rule.execute2()

然后测试通过.

在Spock之外,我只是运行了一个简单的Groovy脚本,并执行了方法重载,并且该方法可以按预期正常工作,并且该方法已使用闭包进行了模拟操作

Outside of Spock I just ran a simple Groovy script and did the method overload and that works correctly as I'd expect and the method is mocked out with the closure

class A {
    def execute () {
        println "thing"
    }
}

def c = new A()
def res
c.execute()

c.metaClass.execute  = {-> res =2 ; println "modified thing "; }

c.execute ()

println "res = "+  res

为什么在Spock测试中不会发生同样的事情?

Why doesn't the same happen in the Spock test?

单元存根如何为Spock正确测试关闭?

How do unit stub test a closure correctly for Spock?

此测试的修改版本成功运行:

This modified version of the test works successfully:

def "test default execution " (){
    given : "basic AORule "

    def mockres

    def stub = new StubFor(AORule)
    stub.demand.execute { mockres = "did nothing" }
//        rule.metaClass.execute = {-> mockres = "did nothing"}     //mock the action
//        def res = rule.execute()

    expect : "execute should do nothing "
    stub.use {
        rule.execute()
        mockres == "did nothing"

    }
}

为什么简单的每个元类在Spock中都不起作用?

Why didn't the simple per metaclass work in Spock?

推荐答案

这是Groovy> = 2.4.3上的一个未解决问题,位于此处:

This is an open issue on Groovy >= 2.4.3, here: GROOVY-7368.

在用元类覆盖私有方法中存在一个错误.

There is a bug in the overriding of private methods with the metaclass.

这篇关于Groovy每个实例的metaClass方法重写无法在Spock测试中按预期工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆