2011-01-20 92 views
3

我想單元測試的一些代碼,返回值看起來與此類似:如何模擬關閉以測試Grails服務結果?

Groovy Service code to test: 
    def findByThisAndThat(something) { 
      : 
     def items = [] 
     sql.eachRow(query, criteriaList, { 
      def item = new Item(name:it.NAME) 
      items.add(item) 
     }) 
     [items: items, whatever:whatevervalue] 
    } 

單元測試代碼計劃:

void testFindByThisAndThatReturnsAMapContainingItems(){ 
     Sql.metaClass.eachRow = { String query, List criteria, Closure c -> 

      // call closure to get passed in items list 
      // add one new Item(name:"test item") to list 
     } 

     def result = service.findByThisAndThat("", "") 

     assert result.items 
     assertEquals('test item', result.items[0].name) 
    } 

我怎麼能這樣做? 謝謝!

回答

1

通過像使用方法一樣調用閉包。或者,您也可以使用Closure.call()。作爲第一個參數傳遞值爲it

Sql.metaClass.eachRow = { String query, List criteria, Closure c -> 
    def mockItems = ["test item"] 
    mockItems.each { item -> 
     c(item) 
     // c.call(item) works too 
    } 
} 

請注意,Sql metaClass在測試結束時不會被重置。我建議在測試後清除它:

Sql.metaClass = null 
2

像你一樣的單元測試提出了真正的測試,只要數據庫中給出正確的數據,就可以將它正確地組裝到Item實例中。我會切換到集成測試,您可以訪問真實的數據庫,並使用db中的測試數據測試整個方法。

單元測試數據庫訪問通常更多地是模擬代碼的測試,而不是代碼的測試,所以它通常沒什麼用處。