У меня есть следующий тест, написанный на 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 заявил. Вы можете мне с этим помочь?
Я ожидаю, что он запустит метод checkPassword с allowedPassword в качестве одного из параметров





Похоже, вы ищете @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.
Теперь, что касается ответа Дмитрия, я просто хочу показать, что вы можете использовать старый добрый 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]")
}
}
Что вы от него ждете?