Ответ 1
Вы использовали бы expect ... change
для проверки того, что вызов определенного метода изменяется или не изменяется - какое-то другое значение. В этом случае:
expect { click_button "Create my account" }.not_to change(User, :count)
приведет к тому, что rspec сделает следующее:
- Запустите
User.count
и обратите внимание на возвращаемое значение. (Это может быть указано как получатель и имя метода, например(User, :count)
в вашем примере, или как произвольный блок кода, например{ User.count }
. - Запустите
click_button "Create my account"
, который является методом Capybara, который имитирует щелчок мышью по ссылке. - Запустите
User.count
снова. - Сравните результаты # 1 и # 3. Если они отличаются, пример не выполняется. Если они совпадают, они проходят.
Другие способы использования expect ... change
:
expect { thing.destroy }.to change(Thing, :count).from(1).to(0)
expect { thing.tax = 5 }.to change { thing.total_price }.by(5)
expect { thing.save! }.to raise_error
expect { thing.symbolize_name }.to change { thing.name }.from(String).to(Symbol)
Некоторые документы здесь.
Как это происходит, это немного загадочно, и совсем не нужно понимать, как это работает, чтобы использовать его. Вызов expect
определяет структуру для rspec для выполнения, используя собственный DSL-интерфейс и систему "сопоставлений". Гэри Бернхардт имеет довольно аккуратный screencast, в котором он утверждает, что тайна rspec фактически выпадает естественным образом из динамического языка, такого как рубин. Это не хорошее введение в использование rspec, но если вам интересно, как все это работает, вам может показаться интересным.
UPDATE
После просмотра комментария к другому ответу я немного добавлю порядок операций. Неинтуитивный трюк заключается в том, что он является совпадающим (change
в этом случае), который выполняет все блоки. expect
имеет lambda, not_to
является псевдонимом для should_not
, задачей которого является передать лямбда на совпадение. Матчи в этом случае change
, который знает, чтобы выполнить свой собственный аргумент один раз, затем выполнить lambda, который он передал (один из expect
), а затем снова запустить свой собственный аргумент, чтобы узнать, изменились ли все. Это сложно, потому что строка выглядит так, как будто она должна выполняться слева направо, но так как большинство частей просто обходят блоки кода, они могут и перетасовывать их в любой порядок, который имеет наибольший смысл для совпадения.
Я не специалист по внутренним функциям rspec, но я понимаю основную идею.