我有一个包含属性对的域类:
Boolean statement1
Boolean statement1Missing
这些对最多可达九个。
以下约束适用于每个配对:
statement1 nullable: true
statement1Missing validator: {val, obj ->
if ( val == true &&
(obj.statement1 == true || obj.statement1 == false)) {
return ['statement.not.missing', 1]
}
if (obj.statement1 == null && val == false) {
return ['statement.is.missing', 1]
}
}
我设计了一个可以容纳一对语句的集成测试:
@Unroll
def "Validation of custom validation for statement1"() {
given: "New data"
def participant = new Data(studyId: "M00001",
formVersion: Version.get(7)
)
and: "an initial set of test values"
participant.statement1 = statement1
participant.statement1Missing = statement1Missing
when: "the validator is invoked"
def isValidConsentData = participant.validate()
then: "the appropriate fields are flagged as errors"
isValidConsentData == anticipatedValid
participant.errors.getFieldError(fieldInError)?.code == errorCode
where:
statement1 | statement1Missing | anticipatedValid | fieldInError | errorCode
true | false | true | null | null
false | false | true | null | null
null | true | true | null | null
null | false | false | "statement1Missing" | "statement.is.missing"
true | true | false | "statement1Missing" | "statement.not.missing"
false | true | false | "statement1Missing" | "statement.not.missing"
}
它处理我想测试的statement1的所有组合。
我一直试图弄清楚如何为所有九个语句对重复这个测试。我试过这样的循环:
(1..9).each { statementNo
...
and ...
participant.("statement" + statementNo) = ("statement" + statementNo)
...
where:
("statement" + StatementNo) | ("statement" + StatementNo + Missing) | ...
}
我之前想要迭代属性时使用过这种类型的迭代,但它在Spock中不起作用。测试完全被忽略了。我真的不想为每个语句对重复这段代码。
我已经研究过使用这种类型的结构http://www.christianoestreich.com/2012/11/domain-constraints-grails-spock-updated/,但这只允许你一次测试一个属性值,而我想多次测试一个属性值。
另一种选择是明确地在'其中'中包含每个属性对。阻止和每一个可能的结果,但这将非常麻烦。
请提供一些关于如何使用迭代结构来执行这些测试的建议。
答案 0 :(得分:1)
如下:
...
and: "an initial set of test values"
(1..9).each { statementNo ->
participant."statement$statementNo" = statement
participant."statement${statementNo}Missing" = statementMissing
}
when: "the validator is invoked"
def isValidConsentData = participant.validate()
then: "the appropriate fields are flagged as errors"
(1..9).each { statementNo ->
def fieldInError
if (anticipatedValid) {
fieldInError = null
} else {
fieldInError = "statement${statementNo}Missing"
}
assert isValidConsentData == anticipatedValid
assert participant.errors.getFieldError(fieldInError)?.code == errorCode
}
where:
statement | statementMissing | anticipatedValid | errorCode
true | false | true | null
false | false | true | null
null | true | true | null
null | false | false | "statement.is.missing"
true | true | false | "statement.not.missing"
false | true | false | "statement.not.missing"
当给定字段没有错误时,不确定它对getFieldError(fieldName)的行为如何,因此如果抛出异常,您可能需要使用!anticipatedValid
为第二个断言添加一些条件。
重要的是隐式assert
是必要的,因为each
是无效的,因此测试根本不会检查任何内容。