Unit testing 如何在Grails中模拟域对象的静态方法?

Unit testing 如何在Grails中模拟域对象的静态方法?,unit-testing,grails,groovy,mocking,Unit Testing,Grails,Groovy,Mocking,有一个Grails域对象,它有一个自定义的静态函数来从数据库中获取数据 class Foo { /* member variables, mapping, constraints, etc. */ static findByCustomCriteria(someParameter, List listParameter) { /* code to get stuff from the database... */ /*

有一个Grails域对象,它有一个自定义的静态函数来从数据库中获取数据

class Foo {
    /* member variables, mapping, constraints, etc. */

    static findByCustomCriteria(someParameter, List listParameter) {
        /* code to get stuff from the database... */

        /*
            Return value is a map
            ["one": "uno", "two": "due", "three": "tre"]
        */
    }

}
静态函数
findByCustomCriteria
使用
createCriteria()
构建从Foo表中提取数据的查询,这意味着在单元测试时,
mockDomain(Foo)
无法正常工作。为了解决这个问题,我正在尝试使用一种通用的模拟方法来模拟
findByCustomCriteria
,但我不能完全正确地理解语法

我有一个控制器
BarController
,我正试图测试它,它被隐藏在对
BarController.someFunction()
的调用中,有一个对
Foo.findByCustomCriteria()
的调用

有什么办法可以嘲弄这一点

我尝试过使用
newmockfor()
MockFor()
元类,但无法使其正常工作


编辑:

每次我试图嘲弄这个,我试图嘲弄它像这样

Foo.metaClass.'static'.findByCustomCriteria = { someParam, anotherParam ->
    ["one": "uno", "two": "due", "three": "tre"]
}

我想我最初没有包含足够的信息。

我不止一次遇到过这种情况,您需要修改Foo的静态元类:

Foo.metaClass.'static'.findByCustomCriteria = { someParameter, List listParameter ->
    ["one": "uno", "two": "due", "three": "tre"]
}

通常我会将它放在测试设置中,这样我就不会忘记何时需要应用它。

在Grails2.0及更高版本中,您可以像这样使用
GrailsMock

def mockControl = new GrailsMock(MyDomainClass)
mockControl.demand.static.get() {id -> return null}  // Static method
...
mockControl.verify()

请参阅。

将mocking和foo的东西放进去……这就是我们需要看到的,以帮助解决方案不起作用。我正在相应地更新这个问题。@haydenmuhl:我更新了解决方案以包含一个显式参数(我假设隐式it参数足够,但可能不够,这可能是问题所在(即方法重载签名))。请再试一次。您的解决方案可能会奏效,但我的问题中没有包含正确的信息。我使用的方法签名是错误的。它实际上包含了一个对象和一个列表,我把它模拟成两个对象。我会更新这个问题。如果您更新您的答案,我将选择它作为正确答案。并确保方法签名匹配;-)我认为关于static的引用是不必要的。
def mockControl = new GrailsMock(MyDomainClass)
mockControl.demand.static.get() {id -> return null}  // Static method
...
mockControl.verify()