2011-06-16 27 views
3

我正在嘗試爲Command對象驗證編寫一些單元測試。 當我的命令對象有許多有多個驗證規則的字段時,爲每個測試用例設置命令對象變得太冗長和重複。爲單元測試禁用驗證約束(使用Spock)

說我有這個命令對象:

class MemberCommand { 
    String title 
    String name 
    String phone 
    static constraints = { 
     title(blank: false, inList: ["Mr", "Mrs", "Miss", "Ms"]) 
     name(blank: false, maxSize:25) 
     phone(blank: false, matches: /\d{8}/) 
    } 
} 

我想要做這樣的事情來測試:

class ValidationTitle extends UnitSpec { 
    def "title must be one of Mr, Mrs, Miss, Ms"() { 
     setup: 
     def memberCommand = new MemberCommand() 
     // I don't want to do: 
     // memberCommand.name = "Spock" 
     // memberCommand.phone = "99998888" 
     // Instead, I want to disable other constraints, except the one for title 
     mockForConstraintsTests MemberCommand, [memberCommand] 

     when: 
     memberCommand.title = t 

     then: 
     memberCommand.validate() == result 

     where: 
     t << ["Mr", "Mrs", "Miss", "Ms", "Dr", ""] 
     result << [true, true, true, true, false, false] 
    } 
} 

這會導致測試失敗,因爲當memberCommand.validate()被調用,所有的約束條件都會被使用,即使在標題「Mr」正在測試的情況下也會導致驗證錯誤。 我可以爲此測試設置名稱和電話號碼,但是,當我測試名稱驗證時,需要設置標題和電話號碼,以及測試手機驗證時的名稱和名稱。您可以想象,如果命令對象的字段更多且規則更復雜,這會如何變得更加煩人。

有沒有在grails中禁用單元測試(使用Spock)約束的方法?

如果沒有,對於這種情況的任何其他建議?

謝謝。

+0

有趣,我遇到了同樣的問題又來了,今天一直在尋找解決方案,以及與此我張貼只是一年前來到了。 – 2012-07-26 01:02:15

回答

3

您無法禁用特定的約束驗證。但是,您可以爲其他屬性提供有效值,或者特別檢查title屬性中的錯誤。

在第一種情況下,你只需從他們創造的默認(合法的)地圖屬性和初始化命令:

def validAttributes = [ title: 'Mr', name: 'Spock', phone: '99998888' ] 

def "title must be one of Mr, Mrs, Miss, Ms"() { 
    setup: 
    def memberCommand = new MemberCommand(validAttributes) 
    mockForConstraintsTests MemberCommand, [memberCommand] 

    when: 
    memberCommand.title = t 

    then: 
    memberCommand.validate() == result 

    where: 
    t << ["Mr", "Mrs", "Miss", "Ms", "Dr", ""] 
    result << [true, true, true, true, false, false] 
} 

這也是很好的做法,即驗證了「基線」的情況下(我在我的測試中始終遵循這種模式)。它表達了你對你的驗證的基本假設。

對於其他的可能性,你會怎麼做:

def "title must be one of Mr, Mrs, Miss, Ms"() { 
    setup: 
    def memberCommand = new MemberCommand() 
    mockForConstraintsTests MemberCommand, [memberCommand] 

    when: 
    memberCommand.title = t 
    memberCommand.validate() 

    then: 
    memberCommand.errors['title'] == result 

    where: 
    t << ["Mr", "Mrs", "Miss", "Ms", "Dr", ""] 
    result << [null, null, null, null, 'not.inList', 'not.inList'] 
} 
+0

謝謝你的建議。非常感激。因爲無論如何我都會開始測試錯誤信息,所以我最終可能會使用兩者的組合,即。具有基準情況並且還檢查字段特定的錯誤。 – 2011-06-20 00:14:16