我有两节课:
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'的情况下完成?
答案 0 :(得分:1)
我建议你重新开始测试。婴儿步骤是我遵循的。 :)
Foo
内创建Bar
和src/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'}
在搜索时我还发现你无法用闭包替换带有选项参数的方法。可能是一个错误