3

コマンドオブジェクト検証用の単体テストを作成しようとしています。コマンドオブジェクトに多くの検証ルールを持つ多くのフィールドがある場合、テストケースごとにコマンドオブジェクトを設定するのは冗長すぎて繰り返しになります。

私がこのコマンドオブジェクトを持っているとしましょう:

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」がテストされている場合でも検証エラーが発生するため、このテストは失敗します。この1つのテストの名前と電話番号を設定できますが、名前の検証をテストするときはタイトルと電話番号を設定し、電話番号の検証をテストするときはタイトルと名前を設定する必要があります。より複雑なルールを持つコマンドオブジェクトへのフィールドが増えると、これがどのように煩わしくなるか想像できます。

Grailsでのユニットテスト(Spockを使用)で制約を無効にする方法はありますか?

そうでない場合、このような状況に対する他の提案はありますか?

ありがとうございました。

4

1 に答える 1

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']
}
于 2011-06-16T12:05:02.077 に答える