Spock测试Grails - 哪个模拟框架选择? [英] Grails Testing with Spock - Which Mocking Framework Select?

查看:128
本文介绍了Spock测试Grails - 哪个模拟框架选择?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有更一般的问题。使用Spock时,我应该在Grails 2.x中使用哪个框架或实现?



我知道很多模仿风格:利用Groovy metaClass,Grails mockFor(),Groovy Mock(),Groovy封闭风格等等。它们每个都有自己的优点和缺点。但我不明白的是,某些嘲笑风格在某些我无法确定的场合起作用(例如,mockFor()适用于某些实现,而不适用于其他实现)。



目前我有两个类似的服务方法执行模拟。



这一个工程:

  @TestFor(MyController)
@Mock([MyDevice])$ b $ class MyControllerSpec extends ControllerSpec {
$ b $ voidtest st。(){
def myService = mockFor(MyService)
myService.demand.myMethod(){def st - >
returntest
}
controller.myService = myService.createMock()
}
}

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

  @TestFor (MyController)
@Mock([MyDevice])
MyControllerSpec扩展ControllerSpec {
$ b $ voidtest st。(){
def yourService = mockFor )
yourService.demand.yourMethod(){def st - >
returntest
}
controller.yourService = yourService.createMock()
}
}

来自控制器的服务实现和调用非常相似。那么在Grails中嘲笑的最佳做法是什么?或者有什么好的嘲笑框架的Grails,这将节省我的时间搞清楚如何模拟?



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



Mateo

解决方案

进行测试,然后尝试利用框架本身提供的选项和样式。

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



我试图让您的测试用例用Spock编写,因为它可以重写as:

  @TestFor(MyController)$ b $ class MyControllerSpec扩展了ControllerSpec {

void (){
//定义设置的行为
setup:只调用一次服务方法
def myService = Mock(MyService){
//确保serviceMethod只从控制器调用一次
// Spock的美丽之处在于您可以测试
//方法调用的基数。
1 * serviceMethod()>> 你好
}
controller.myService = myService

//上面的过程可以遵循
//用于存根/嘲弄'YourService'和
//然后将其注入到控制器中,如
//controller.yourService = yourService

//定义操作行为
当:controller action called
controller.myAction()

//定义预期结果的行为
然后:期望存根服务方法输出
controller.response.contentAsString ==Hello



//控制器
def myAction(){
render myService.serviceMethod()
}

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

有关如何有效使用spock框架的更多细节,请访问spock框架文档


I have more general question. Which framework or implementation I should use for mocking in Grails 2.x when using Spock?

I know tons of mocking style: leverage Groovy metaClass, Grails mockFor(), Groovy Mock(), Groovy closure style, etc. Each of them has its own advantages and disadvantages. But what I don't understand is that some mocking style works in certain occasions which I cannot determine (i.e. mockFor() works for certain implementation and not for the others).

Currently I have two similar implementation of service method mocking.

This one works:

@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()
}
}

However, this implementation doesn't work:

@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()
}
}

The service implementation and calling from controller is quite similar. So what is the best practice of mocking in Grails? Or is there any GOOD mocking framework for Grails which would save my time figuring out how to mock?

Thanks for any advice! :-)

Mateo

解决方案

When you are using spock framework for testing, then try to leverage the options and styles provided by the framework itself.

Spock framework helps in achieving a BDD [Behavioral Design Development]. By behavior I meant, you can tightly couple the business acceptance scenario to the development cycle.

I tried to get your test case written in Spock as it can be re-written as:

@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()
}

If you see above, you define the behavior in each step. From an enterprise perspective, those behavior will be driven by BA or the stakeholders. By this way, you comply to ATDD/BDD(Acceptance Test Driven Dev/Behavior Test Driven Dev) and eventually a TDD(Test Driven Dev) for your project.

For more details on how to use spock framework effectively, visit spock framework docs.

这篇关于Spock测试Grails - 哪个模拟框架选择?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆