2011-05-04 63 views

回答

2

您可以使用Groovy metaClass覆蓋domain類的beforeDelete方法。

域類:

class Person { 
    String name 
    boolean deleted 

    def beforeDelete() { 
    println "Deleting Person ${id}" 
    deleted = true 
    return false 
    } 
} 

單元測試:

void testBeforeDelete() { 
    mockDomain(Person) 
    def p = new Person(name:"test") 
    p.save() 
    assertEquals false, p.deleted 
    p.delete() 
    assertEquals true, p.deleted 
} 

--output從testBeforeDelete--

刪除個人從testBeforeDeleteOverr 1

void testBeforeDeleteOverrideBeforeDelete() { 
    mockDomain(Person) 
    Person.metaClass.'static'.beforeDelete = {println 'Do not touch me'} 
    def p = new Person(name:"test") 
    p.save() 
    assertEquals false, p.deleted 
    p.delete() 
    assertEquals true, p.deleted 
} 

--output ideBeforeDelete--

不要碰我

+1

太棒了!謝謝,大衛。你能告訴我在這種情況下'靜態'意味着什麼? – user569825 2011-05-05 12:03:19

+1

[Groovy Docs](http://groovy.codehaus.org/JN3525-MetaClasses#JN3525-MetaClasses-ExpandoMetaClass)在上面的例子中,我們使用ExpandoMetaClass在Person類上添加/重寫一個靜態方法。 – 2011-05-05 14:25:33

1

像往常一樣用mockDomain模擬域類,然後在該特定的單元測試中模擬beforeDelete關閉與mockFor。例如:

void testDelete() { 
    mockDomain(MyDomainClass) 
    def myDomainClassControl = mockFor(MyDomainClass) 
    myDomainClassControl.demand.beforeDelete(1..1) { -> println "hello world" } 

    ... // test delete 

    myDomainClassControl.verify() 
} 
+0

如何獲取域類的實例?當我在** md.save()**上執行** def md = new MyDomainClass()**和更高版本時,測試仍然運行** original originalDelete()**。另一方面,如果我執行** def md = myDomainClassControll.createMock()**,則md.save()會導致** java.lang.IllegalArgumentException:參數類型不匹配** – user569825 2011-05-04 18:01:15

+0

**參數類型不匹配**似乎只消失*當我刪除** mockDomain(MyDomainClass)** - 但然後我收到** junit.framework.AssertionFailedError:驗證[2]:預期1..1調用('s)'beforeDelete',但被稱爲0次(s)。** – user569825 2011-05-04 18:03:29

+0

好吧,'beforeDelete'事件似乎沒有在grails 1.3.7下的單元測試中被解僱。作爲替代方案,我建議將測試轉換爲集成測試。 – ataylor 2011-05-04 19:30:05