繁体   English   中英

禁用 grails 命令对象中的验证约束以进行单元测试(使用 Spock)

[英]Disabling a validation constraint in grails command object for unit testing (with Spock)

我正在尝试为 Command 对象验证编写一些单元测试。 当我的命令对象有许多具有许多验证规则的字段时,为每个测试用例设置命令对象变得过于冗长和重复。

假设我有这个命令对象:

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() 时,将使用所有约束,并且即使在测试标题“先生”的情况下也会导致验证错误。 我可以为这个测试设置名称和电话,但是,我需要在测试名称验证时设置标题和电话,以及在测试电话验证时设置标题和名称。 您可以想象,当命令对象有更多字段且规则更复杂时,这会变得更加烦人。

有没有办法在 grails 中禁用单元测试(使用 Spock)中的约束?

如果没有,对于这种情况还有其他建议吗?

谢谢你。

您不能禁用特定的约束验证。 但是,您可以为其余属性提供有效值,或者特别检查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']
}

可以通过将数组作为参数并将其名称作为字符串传递来仅测试您想要的属性:

then:
memberCommand.validate(['title']) == result

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM