当我希望在许多相似的领域执行相同的测试时,如何在 Grails Spock 测试中迭代测试?
How do I iterate over tests in Grails Spock testing when I wish to perform the same tests on many similar fields?
我有一个域 class 有 属性 对:
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"
}
这处理了我希望测试的语句 1 的所有组合。
我一直在想办法对所有九个语句对重复这个测试。我试过这样循环:
(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/ 但这只允许您一次测试一个 属性 值,而我想测试一个 属性 值很多次。
另一种选择是在 'where' 块中明确包含每个 属性 对和每个可能的结果,但这会非常麻烦。
请提供一些关于如何使用迭代结构来执行这些测试的建议。
怎么样:
...
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
是无效的,否则测试根本不会检查任何内容。
我有一个域 class 有 属性 对:
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"
}
这处理了我希望测试的语句 1 的所有组合。
我一直在想办法对所有九个语句对重复这个测试。我试过这样循环:
(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/ 但这只允许您一次测试一个 属性 值,而我想测试一个 属性 值很多次。
另一种选择是在 'where' 块中明确包含每个 属性 对和每个可能的结果,但这会非常麻烦。
请提供一些关于如何使用迭代结构来执行这些测试的建议。
怎么样:
...
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
是无效的,否则测试根本不会检查任何内容。