2016-11-06 56 views
0

我正在寫一個簡單的集成測試,我打算模擬刪除失敗。如何覆蓋gorm刪除方法進行測試?

控制器只需從數據庫中提取記錄並將其刪除,如下所示。

def deleteItem(id){ 


    def item = Item.get(id) 

    item.delete() 

} 

現在,我想模擬刪除失敗與下面的代碼

void testDeleteItem_FailDeleteFlushSaveFail(){ 


    Item.metaClass.delete = { Map params -> 

     throw new ValidationException("Failed!!") 

    } 



    def model = controller.deleteItem(mp.id) 


    assertEquals controller.flash.message, "Sorry an error occured when deleting!!" 



    GroovySystem.metaClassRegistry.removeMetaClass(Item.class) 



} 

但由於方法不更換測試失敗。即在刪除時不會引發異常。我猜測問題出在我的元類中。我怎樣才能使它在調用刪除時拋出異常?我感謝任何幫助!謝謝!

回答

-1

嘗試,使用:

Item.metaClass.'static'.delete = { Map params -> 
    throw new ValidationException("Failed!!") 
} 
0

這是因爲你應該使用

Item.metaClass.delete = { 

     throw new ValidationException("Failed!!") 

    } 

而不是

Item.metaClass.delete = { Map params -> 

     throw new ValidationException("Failed!!") 

    } 
0

首先,我不認爲這個問題應該是最低票數。對於您想要測試程序如何對失敗做出反應的場景,這是一個有效的問題。

有幾件事錯在這裏:

  • Domain.delete不會拋出validationExceptions。另外ValidationExceptions由兩個參數(String msg,Errors error)構造而成。您需要向您的域類添加自定義錯誤並將域類傳入。再次,這對刪除沒有意義,因爲誰需要在刪除時驗證對象? 不知道你正在運行的版本,但這裏是2.5.1(Grails 2.5.1 docs - 見7.3.2刪除對象)的文檔

    高清P = Person.get(1) 嘗試{ p.delete(齊平:true) } catch(org.springframework.dao.DataIntegrityViolationException e){ flash.message =「無法刪除人員$ {p.name}」 redirect(action:「show」,id:p.id) }

  • 其次,刪除(failOnError:true)。我不確定這是否做任何事情。相反,你應該在try catch中包圍你的delete方法,並使用flush:true選項。

    try{ 
        item.delete(flush:true) 
    }catch(DataIntegrityViolationException e){ 
        flash.message = "Sorry an error occurred when deleting!!" 
    } 
    
  • 第三,mp.id來自哪裏?我們是否遺漏了測試文件的一部分。如果不是,您的測試似乎依賴於已經存在的數據。即使在集成測試中,爲了防止由於缺少數據而造成的測試污染和失敗的測試,您也可以單獨爲每項測試創建數據。

  • 最後,我還沒有能夠在我的集成測試中正確metaClass域類本身...所以我會推薦你​​metaClass域測試中的實例。下面是一個例子: 忘了包括 '地圖PARAMS - >'

    //creating test data 
    def item = new Item(name: 'testName') 
    
    def model = controller.deleteItem(item.id) 
    
    item.metaClass.delete = {Map params -> 
        throw new DataIntegrityViolationException('Some error message') 
    } 
    
    assertEquals controller.flash.message, "Sorry an error occurred when deleting!!" 
    

    編輯1只注意在元類閉合:

MetaClass的域實例方法。 (在所有版本的grails中可能都不需要,因爲這些方法在版本中的編譯方式有所不同)