你如何在Grails中模拟一个域对象的静态方法?

hay*_*uhl 10 grails groovy unit-testing mocking

有一个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"]
        */
    }

}
Run Code Online (Sandbox Code Playgroud)

静态函数findByCustomCriteria用于createCriteria()构建从Foo表中提取数据的查询,这意味着mockDomain(Foo)在单元测试时无法正常工作.我正在尝试解决这个问题的方法是使用模拟的通用方法之一进行模拟findByCustomCriteria,但我无法正确理解语法.

我有一个控制器BarController,我正在尝试测试,并埋在呼叫中BarController.someFunction()有一个呼叫Foo.findByCustomCriteria().

class BarControllerTest extends ControllerUnitTestCase {

    protected void setUp() {
        super.setUp()
    }

    protected void tearDown() {
        super.tearDown()
    }

    void testSomeFunction() {

        /* Mocking for Foo goes here */

        assertEquals("someValue", controller.someFunction())
    }
}
Run Code Online (Sandbox Code Playgroud)

什么是嘲笑这个的方法?

我已经尝试使用new MockFor(),mockFor()以及metaClass,但我不能得到它的工作.


编辑:

每当我试图嘲笑这个时,我都试着嘲笑它......

Foo.metaClass.'static'.findByCustomCriteria = { someParam, anotherParam ->
    ["one": "uno", "two": "due", "three": "tre"]
}
Run Code Online (Sandbox Code Playgroud)

我想我最初没有提供足够的信息.

Ste*_*sen 14

我不止一次遇到过这个场景,你需要修改Foo 的静态 metaClass:

Foo.metaClass.'static'.findByCustomCriteria = { someParameter, List listParameter ->
    ["one": "uno", "two": "due", "three": "tre"]
}
Run Code Online (Sandbox Code Playgroud)

通常我会把它放在测试设置中,所以我不会忘记何时需要应用它.


Lam*_*bda 5

在Grails 2.0及更高版本中,您可以使用这样的GrailsMock

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

这里