Rails и Rspec - проверка на наличие ошибок при сбое отправки формы - PullRequest
6 голосов
/ 21 октября 2011

У меня есть модель Foo, где : имя требуется при создании.

Я пишу спецификацию для проверки правильности

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"), но я бы предпочел не связывать мои интеграционные тесты с контентом

Ответы [ 3 ]

12 голосов
/ 21 февраля 2013

Если вы правильно тестируете свои проверки на уровне модульного тестирования, добавить еще один тест для нужного сообщения об ошибке очень просто:

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] без необходимости явно проверять каждое сообщение об ошибке на уровне просмотра.

6 голосов
/ 21 октября 2011

Вы сказали, что пишете спецификацию для проверки валидаций, но я вижу, что вы тестируете в капибаре (или аналогичной) с помощью "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

Таким образом, вы тестируете изолированно - только то, что вам нужно проверить, а не то, является ли контроллерработает правильно, или вид, или даже циклически проходя вспышку.

Таким образом, ваш тест будет быстрым, долговечным и изолированным.

1 голос
/ 21 октября 2011

Ваш блок it говорит, что «не должен создавать недопустимый Foo», и, если это действительно то, что вы тестируете, выполните юнит-тест на модели Foo, а не интеграционный тест.

Однако, если вы проверяете СПЕЦИФИЧЕСКОЕ сообщение об ошибке на странице, вам необходимо проверить его содержимое. Чтобы сделать тест менее связанным, вы можете проверить наличие определенного элемента HTML. Например, мои ошибки отображаются во флэш-сообщении. Я проверяю их, ища div с классом с именем error или alert. Я игнорирую реальное сообщение и просто проверяю, появляется ли НЕКОТОРАЯ ошибка.

...