2013-07-24 54 views
8

我有更一般的问题。在使用Spock时,我应该在Grails 2.x中使用哪个框架或实现进行嘲讽?我知道大量的嘲笑风格:利用Groovy metaClass,Grails mockFor(),Groovy Mock(),Groovy闭包风格等。每种方法都有其优点和缺点。但我不明白的是,某些嘲笑风格在某些我无法确定的场合下工作(即mockFor()适用于某些实现,而不适用于其他场合)。使用Spock进行Grails测试 - 哪个模拟框架选择?

目前我有两个类似的服务方法嘲笑的实现。

这一个工程:

@TestFor(MyController) 
@Mock([MyDevice]) 
class MyControllerSpec extends ControllerSpec { 

void "test st."() { 
     def myService = mockFor(MyService) 
     myService.demand.myMethod() { def st -> 
     return "test" 
     } 
     controller.myService = myService.createMock() 
} 
} 

然而,这种实现不起作用:

@TestFor(MyController) 
@Mock([MyDevice]) 
class MyControllerSpec extends ControllerSpec { 

void "test st."() { 
     def yourService = mockFor(YourService) 
     yourService.demand.yourMethod() { def st -> 
     return "test" 
     } 
     controller.yourService = yourService.createMock() 
} 
} 

服务实现,并从控制器调用颇为相似。那么在Grails中嘲笑的最佳做法是什么?还是有没有什么好的嘲笑框架的Grails,这将节省我的时间搞清楚如何模拟?

感谢您的任何建议! :-)

+1

你有没有试过Spock的模拟框架?它非常清楚和直接。 spock文档说它可以与spock mock或Groovy mock一起工作,但是警告不要因为某种原因尝试结合使用这两个模拟框架。 –

+0

是的,这实际上是当你调用mockFor()时会用到的。调用grails.plugin.spock.UnitSpec.mockFor()。我发现最有用的是直接使用metaClass编程进行模拟以及常规闭包。唯一的问题是,当你不在威胁下降部分清理它时,metaClass可能会干扰其他测试。 也许Grails 2.3会带来更好的支持,因为Spock是这个版本的默认设置... – kuceram

+0

如果答案是合适的并且符合您的期望,那么接受它以帮助其他人从您的问题中学习。 – dmahapatro

回答

7

当您使用测试斯波克框架,然后尝试利用由框架提供的选项和样式。

Spock框架有助于实现BDD [行为设计开发]。按照我的意思,您可以将业务接受场景紧密地与开发周期相耦合。

我试图让你的测试用例编写斯波克,因为它可以被重新写为:

@TestFor(MyController) 
class MyControllerSpec extends ControllerSpec { 

    void "test service method in called once and only once"(){ 
     //Defines the behavior of setup 
     setup: "Only one invocation of service method" 
      def myService = Mock(MyService){ 
       //Make sure serviceMethod is called only once from the controller 
       //Beauty of Spock is that you can test the cardinality of 
       //method invocations. 
       1 * serviceMethod() >> "Hello" 
      } 
      controller.myService = myService 

      //The above process can be followed 
      //for stubbing/mocking 'YourService' and 
      //then injecting it to controller like 
      //controller.yourService = yourService 

     //Defines the behavior of action 
     when: "controller action is called" 
      controller.myAction() 

     //Defines the behavior of expected results 
     then: "Expect the stubbed service method output" 
      controller.response.contentAsString == "Hello" 
    } 
} 

//Controller 
def myAction() { 
    render myService.serviceMethod() 
} 

如果你看到上面,您可以定义每个步骤的行为。从企业角度来看,这些行为将由BA或利益相关方推动。通过这种方式,您可以遵守ATDD/BDD(验收测试驱动开发/行为测试驱动开发)并最终为您的项目开发TDD(测试驱动开发)。

有关如何有效使用spock框架的更多详细信息,请访问spock框架docs

相关问题