我有更普遍的问题。在使用Spock时,我应该在Grails 2.x中使用哪个框架或实现进行模拟?
我知道大量的模拟风格:利用Groovy metaClass,Grails mockFor(),Groovy Mock(),Groovy闭包样式等等。每个都有自己的优点和缺点。但我不明白的是,某些模拟风格在某些我无法确定的场合起作用(即mockFor()适用于某些实现而不适用于其他实现)。
目前我有两种类似的服务方法模拟实现。
这个有效:
@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有什么好的模拟框架可以节省我的时间来弄清楚如何模拟?
感谢您的任何建议! : - )
圣马特奥
答案 0 :(得分:8)
当您使用spock框架进行测试时,请尝试利用框架本身提供的选项和样式。
Spock框架有助于实现BDD [行为设计开发]。按照我的意思,您可以将业务接受方案与开发周期紧密结合。
我试图用Spock编写测试用例,因为它可以重写为:
@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。