用元类中的闭包替换带参数的方法

时间:2013-05-23 12:33:12

标签: grails groovy grails-2.2

我有两节课:

class Foo {
    String doSomething(String a, String b) {
        return 'Not Working'
    }
}


class Bar {
    String methodIWannaTest() {
        return new Foo().doSomething('val1', 'val2')
    }
}

我想在测试中替换'doSomething',但它确实有效

class BarTests {
    @Test
    void testMethodIWannaTest() {
        Foo.metaClass.doSomething {String a, String b -> return 'Working'}

        assert new Bar().methodIWannaTest() == 'Working' //THIS TEST FAIL, return 'Not Working'
    }
}

*我知道测试并没有真正发挥作用,只是为了表明我的观点

我做错了什么?是否可以在不使用'mockFor'的情况下完成?

4 个答案:

答案 0 :(得分:1)

我建议你重新开始测试。婴儿步骤是我遵循的。 :)

  • 创建一个新的grails应用程序。
  • 在包裹下的Foo内创建Barsrc/groovy
  • 从命令提示符创建单元测试用例。输入所需的测试代码。
  • 执行grails test-app

[Grails v2.2.0]

答案 1 :(得分:1)

另一种选择是使用Groovy MockFor

def mock = MockFor(Foo)
mock.demand.doSomething = {String a, String b -> return 'Working'}
mock.use {
  assert new Bar().methodIWannaTest() == 'Working'
}

缺点是was a bug,单元测试不清楚模拟。这是针对2.2.3修复的。

答案 2 :(得分:0)

我在 GGTS 3.2.0 上尝试了此操作,并获得了以下结果。

复制所有代码并在Grails 2.2.2上运行:一切正常。然而,然后我评论了Foo.metaClass.doSomething = {String a, String b -> return 'Working'}行,令人惊讶的是,测试仍然成功通过。我做了更多更改,metaClass似乎在测试之间“缓存”:更改没有效果。

然后我想如果Grails可能以交互模式运行。去偏好> Groovy> Grails> Grails启动,找到一个复选框'保持外部Grails运行'。它的工具提示甚至包含以下词语:'警告:实验性功能!'。取消选中该复选框,并且不再在测试运行之间缓存metaClass。我仍然想知道为什么默认情况下会启用一个实验性功能......

答案 3 :(得分:0)

我发现了问题:

首先,在我的例子中,我忘记了' ='在定义闭包时

Foo.metaClass.doSomething {String a, String b -> return 'Working'}

应该是

Foo.metaClass.doSomething = {String a, String b -> return 'Working'}

在搜索时我还发现你无法用闭包替换带有选项参数的方法。可能是一个错误