MissingPropertyException при запуске теста в spock

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

Что вы от него ждете?

tim_yates 30.07.2018 21:57

Я ожидаю, что он запустит метод checkPassword с allowedPassword в качестве одного из параметров

randomuser1 30.07.2018 22:01
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
2
1 445
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Похоже, вы ищете @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]")
  }
}

Другие вопросы по теме