我有groovy
编写的以下测试(使用spock
框架时):
def "#checkPassword check if passwd match"() {
given:
def allowedPasswords = ["1", "2"]
expect:
myStrategy.checkPassword(myModel, input) == result
where:
input | result
allowedPasswords | true
}
但是,当我运行它时,allowedPasswords
字段似乎丢失了。我收到以下错误:
groovy.lang.MissingPropertyException: No such property: allowedPasswords for class:
我想知道为什么,因为我在given
部分中声明了它。你能帮我吗?
答案 0 :(得分:3)
看起来就像您在寻找@Shared
:
import spock.lang.Shared
import spock.lang.Specification
class SpockTest extends Specification {
@Shared allowedPasswords = ["1", "2"]
def "#checkPassword check if passwd match"() {
expect:
checkPassword(input) == result
where:
input << allowedPasswords
result << allowedPasswords
}
static String checkPassword(String input) {
return input
}
}
答案 1 :(得分:2)
出现问题的原因是where:
块在逻辑上属于文本固定装置-请记住,如果使用@Unroll
“ where”变量值甚至会编译为方法名!请参阅下面的示例代码。也就是说,where:
在given:
块之前被评估,因此您不能期望它知道在测试期间稍后初始化的局部变量。
关于其余的测试代码:如果没有重复使用allowedPasswords
,我的建议是直接内联它。仅当您重复使用有问题的变量并且不想内联两次以简化测试维护时,才可以使用您已经接受的答案或我将向您显示的答案。当然,德米特里的答案很好。但是,如果不重新使用它,则会使测试代码有些混乱,从而使其更难以阅读和理解。我建议您为提高可读性而努力,因为良好的BDD测试是应用程序行为的规范,因此Spock测试的基类名称为Specification
和Geb基类名称为GebSpec
。
现在关于德米特里(Dmitry)的答案,我只想表明您可以使用旧的static
来代替@Shared
,并且还提供了示例代码,并进行了一些重用,从而使代码更有意义,并且也更接近您自己的测试用例。我不希望您接受此答案而不是他的任何方式,因为他在我之前已经正确回答了。我只是在这里分享其他细节,没有什么新鲜的。在他的回答中,我只是缺少了为什么您的代码不起作用的解释,因此我也不得不回答。 :-)
package de.scrum_master.stackoverflow
import spock.lang.Specification
import spock.lang.Unroll
class AllowedPasswordsTest extends Specification {
static allowedPasswords = ["1", "2"]
@Unroll
def "password check for '#input' should return #result"() {
expect:
checkPassword(input) == result
where:
input << allowedPasswords + ["3", "oops", " ", null]
result = input in allowedPasswords
}
static boolean checkPassword(String input) {
return input?.trim()?.matches("[12]")
}
}