2013-07-24 85 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

相關問題