#ruby-on-rails #ruby-on-rails-3 #rspec #rspec2
#ruby-on-rails #ruby-on-rails-3 #rspec #rspec2
Вопрос:
У меня есть модель Foo, где при создании требуется :name .
Я пишу спецификацию для проверки проверок
it 'should not create an invalid Foo' do
fill_in "Name", :with=>""
# an error message will be displayed when this button is clicked
click_button "Create Foo"
end
Как я могу подтвердить, что сообщение об ошибке присутствует на странице?
Я пробовал page.errors.should have_key(:name)
, но это неправильно.
Думаю, я мог бы сделать page.should have_content("Name can't be blank")
, но я бы предпочел не связывать мои интеграционные тесты так сильно с контентом
Комментарии:
1. Если вы хотите проверить, присутствует ли сообщение об ошибке на странице, я не думаю, что у вас есть выбор, кроме как, ну, протестировать содержимое. Вы могли бы использовать более конкретный тест на основе селектора, чтобы вы не просто проверяли текст сообщения об ошибке.
2. спасибо, я вас понял. Тогда я просто сделаю это.
Ответ №1:
Если вы правильно проверяете свои проверки на уровне модульного тестирования, добавить еще один тест для желаемого сообщения об ошибке несложно:
describe Foo do
describe "validations" do
describe "name" do
before { @foo = FactoryGirl.build(:foo) } # or Foo.new if you aren't using FactoryGirl
context "when blank" do
before { @foo.name = "" }
it "is invalid" do
@foo.should_not be_valid
end
it "adds the correct error message" do
@foo.valid?
@foo.errors.messages[:name].should include("Name cannot be blank")
end
end # positive test case omitted for brevity
end
end
end
Таким образом, вы изолируете генерацию ошибок и копируете их в модель, и она надежно протестирована, что позволяет вам реализовать какое-то глобальное отображение ошибок (например, с помощью flash[:error] , без необходимости явно проверять каждое сообщение об ошибке на уровне представления.
Комментарии:
1. Спасибо, я предпочитаю этот метод.
Ответ №2:
Вы сказали, что пишете спецификацию для проверки проверок, но я вижу, что вы тестируете в capybara (или аналогичном) с помощью «fill_in»
Вместо этого я настоятельно рекомендую писать модульные тесты для тестирования ваших моделей.
spec/models/your_model_spec.rb
require 'spec_helper'
describe YourModel do
it "should not allow a blank name" do
subject.name = ""
subject.should_not be_valid
subject.should have(1).error_on(:name)
end
end
Таким образом, вы тестируете изолированно — только то, что вам нужно проверить, а не то, правильно ли работает контроллер, или представление, или даже цикл через flash.
Таким образом, ваш тест будет быстрым, надежным и изолированным.
Ответ №3:
В вашем it
блоке написано «не следует создавать недопустимый Foo», и если это действительно то, что вы тестируете, выполните модульный тест на модели Foo, а не интеграционный тест.
Однако, если вы тестируете КОНКРЕТНОЕ сообщение об ошибке на странице, вам нужно проверить содержимое. Чтобы сделать тест менее связанным, вы могли бы проверить наличие определенного элемента html. Например, мои ошибки отображаются во флэш-сообщении. Я проверяю их, ища div с классом с именем error
or alert
. Я игнорирую фактическое сообщение и просто проверяю, чтобы убедиться, что появляется какая-то ошибка.
Комментарии:
1. спасибо, я перенесу проверочные тесты в спецификации модели, теперь это имеет смысл