在 spock 中运行测试时出现 MissingPropertyException



我用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部分声明了它。你能帮我吗?

看起来就像你在寻找@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
}
}

出现问题的原因是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]")
}
}

最新更新