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

Posted

技术标签:

【中文标题】如何在 Grails 中模拟域对象的静态方法?【英文标题】:How do you mock out a static method of a domain object in Grails? 【发布时间】:2011-05-02 16:22:18 【问题描述】:

拥有一个 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"]

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

【问题讨论】:

把 mocking 和 foo 的东西放进去......这就是我们需要看到的帮助 【参考方案1】:

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

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

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

【讨论】:

此解决方案不起作用。我正在相应地更新问题。 @haydenmuhl:我更新了解决方案以包含一个显式参数(我假设隐式 it 参数就足够了,但可能不是,这可能是问题(即方法重载签名))。请重试。 您的解决方案可能会奏效,但我的问题中没有包含正确的信息。我使用的方法签名是错误的。它实际上接受了一个对象和一个列表,我将它嘲笑为接受两个对象。我会更新问题。如果你更新你的答案,我会选择它为正确的。 并确保方法签名匹配;-) 我不认为 static 周围的引号是必要的。【参考方案2】:

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

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

见here。

【讨论】:

以上是关于如何在 Grails 中模拟域对象的静态方法?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Grails 中复制域对象?

如何在 Spock 控制器测试中模拟 Grails 请求对象方法

JavaSE对象

PowerMockito 模拟单个静态方法并返回对象

Grails 覆盖插件服务静态方法

在java中,为啥类实例也能访问静态域?