如何在 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 中模拟域对象的静态方法?的主要内容,如果未能解决你的问题,请参考以下文章