2011-03-06 56 views
5

我想测试控制器使用正确的参数调用service方法。什么是最好的方式来做到这一点?Grails mockFor以及如何测试该方法使用正确的参数调用

我目前的计划是使用mockFor,然后通过闭包检查传入的值。是否有更好的方法通过mockFor或模拟对象执行测试,类似于我可以使用mockito执行相同方法调用参数值测试?

class HappyControllerTests extends ControllerUnitTestCase { 
     : 
    void testSomeValue() { 
     def mockControl = mockFor(HappyService) 
     def givenSomeItem = null 
     mockControl.demand.serviceMethod(1..99) { String someItem -> givenSomeItem = someItem; } 
     controller.happyService = mockControl.createMock() 

     controller.someAction() 

     mockControl.verify() 
     assertEquals("specific value", givenSomeItem) 
    } 
} 

谢谢!

+0

我喜欢“泰德Naleid”的答案。然而,恕我直言,大型商店应该使用mockFor(..)参见http://grails.org/doc/latest/guide/9.%20Testing.html#9.2集成测试“...使用这些方法可确保您做出的任何更改给定的类别不会泄漏到其他测试中。“ – finneycanhelp

回答

13

我很少用mockFor因为我发现Groovy的内置元类的东西,as ClassName更容易的工作与越来越强大,我应该这样做:

void testSomeValue() { 
    def givenSomeItem = null 
    controller.happyService = [ 
     serviceMethod: { String someItem -> givenSomeItem = someItem } 
    ] as HappyService 

    controller.someAction() 
    assertEquals "specific value", givenSomeItem 
} 
+1

感谢您的代码示例。这也是我的观点,直到发生一些事情:1)我参加了杰夫布朗的精彩演讲并与他交谈。 2)在测试的setup()中,我看到metaClass有时会对某个类的所有实例进行操作,但未正确还原。这最终导致了跨测试的副作用行为,我是追捕发生的事情的人。所以..虽然可能只是使用Groovy metaClass来实现对象模拟,而对于其他模型,我建议在大型Java商店中使用mockFor。 – finneycanhelp

+1

如果您更改类上的metaClass,通常会遇到您正在讨论的问题。如果你只是修改一个实例(就像上面的例子一样),它几乎总是安全的,只要实例存在,变化就会一直存在。我唯一遇到这个问题的时候是当我嘲笑注入一个单例的spring实例时。同一个实例已经注入其他地方,所以我的更改在测试后不会被丢弃。我并不完全不同意你的看法,即使人们对groovy不太熟悉,mockFor在一家大型Java商店中可能会更好。 –

+0

这真的很棒 – tbruyelle

相关问题