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

时间:2010-10-30 00:09:27

标签: 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... */

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

}

静态函数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())
    }
}

什么方法可以嘲笑这个?

我尝试过使用new MockFor()mockFor()metaClass,但我无法让它发挥作用。


编辑:

每当我试图嘲笑这件事时,我都试图嘲笑它......

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

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

2 个答案:

答案 0 :(得分:14)

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

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

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

答案 1 :(得分:4)

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

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

请参阅here