Я использую FactoryGirl и Rspec для своей тестовой среды. У меня есть модель, на которой есть проверка validates_presence_of. Базовый фреймворк Rspec включает тест:

describe "with invalid params" do
  it "assigns a newly created but unsaved disease as @disease" do
    # Trigger the behavior that occurs when invalid params are submitted
    Disease.any_instance.stub(:save).and_return(false)
    post :create, :disease => {}
    assigns(:disease).should be_a_new(Disease)
  end
end

Редактировать: diseases_controller.rb

 # POST /diseases
 # POST /diseases.xml
 def create
   @disease = Disease.new(disease_params)

   respond_to do |format|
     if @disease.save
       format.html { redirect_to(@disease, :notice => 'Disease was successfully created.') }
       format.xml  { render :xml => @disease, :status => :created, :location => @disease }
     else
       format.html { render :action => "new" }
       format.xml  { render :xml => @disease.errors, :status => :unprocessable_entity }
     end
   end
 end

 private
 def disease_params
   params.require(:disease).permit(:name, :omim_id, :description)
 end

Этот тест не работает с тем, как работает мое приложение. Вместо того, чтобы возвращать новое заболевание в неправильном сообщении, он возвращает ошибку:

Required parameter missing: disease

Вопрос №1: Я не знаю, как посмотреть, что возвращается с помощью Rspec. В этом случае объект response не создается? Печать assigns(:disease), похоже, ничего не содержит. Я получил сообщение об ошибке, которое я опубликовал ранее, отправив сообщение cURL на правильный URL-адрес с пустыми данными (это то, что должно делать сообщение rspect), но я не знаю, как получить информацию о том, что Rspec получает обратно от сообщение по почте.

Вопрос № 2: Как мне правильно проверить ответ, который должен появиться - что он получает сообщение об ошибке, говорящее об отсутствии обязательного параметра?

Edit: Итак, мой контроллер, кажется, указывает, что он должен отображать новую болезнь, но тест не проходит. Если я пытаюсь сообщить о болезни, в которой отсутствует обязательный параметр на веб-сайте, появляется сообщение «Имя не может быть пустым». Я не уверен, как это проверить в rspec.

Редактировать # 2: Включил код выше. Болезнь_парамс определяется в нижней части контроллера в соответствии с рекомендациями по использованию гема strong_parameters.

Благодарность!

3
Denise Mauldin 27 Мар 2013 в 00:02
Где вы определяете disease_params?
 – 
apneadiving
27 Мар 2013 в 00:31
Похоже, здесь не работает params.require(:disease) но я не могу сказать почему
 – 
apneadiving
27 Мар 2013 в 01:08
У вас есть драгоценный камень strong_parameters? params.require (: болезнь) ищет хеш вида: Parameters: {"disease"=>{"name"=>"Disease 4", "omim_id"=>nil, "description"=>nil}}
 – 
Denise Mauldin
27 Мар 2013 в 01:56
Хм ... ну, если я изменю сообщение на post :create, :disease => { :name => ''}, тогда тест пройдет успешно ... Я не уверен, почему. '' по-прежнему не должен проходить проверку validates_presence_of, верно?
 – 
Denise Mauldin
27 Мар 2013 в 02:06
Вы вставили save в любой экземпляр Disease, поэтому проверки модели не выполняются.
 – 
zetetic
29 Мар 2013 в 05:36

1 ответ

Лучший ответ

Чтобы ответить на вопрос 1 ("Я не знаю, как посмотреть, что возвращается с помощью Rspec, делает сообщение") ... Вы можете использовать операторы "put" в своей спецификации (т.е. в блоке it) . Например, вы можете попробовать что-то вроде этого:

describe "with invalid params" do
  it "assigns a newly created but unsaved disease as @disease" do
    # Trigger the behavior that occurs when invalid params are submitted
    Disease.any_instance.stub(:save).and_return(false)
    post :create, :disease => {}
    puts :disease
    assigns(:disease).should be_a_new(Disease)
  end
end

Это ценный инструмент для отладки. Выходные данные будут в .s и F в терминале, когда RSpec работает.

Что касается вопроса 2, я не совсем уверен, что вы ищете, но я не знаю, нужно ли (или нужно) проверять, что недействительной болезни присвоено значение @disease. Я предпочитаю моделировать спецификации контроллера в следующем стиле (взято из Everyday Rails Тестирование с помощью RSpec, где я научился писать спецификации контроллера).

Пример создания спецификации POST:

context "with invalid attributes" do
  it "does not save the new contact" do
    expect{
      post :create, contact: Factory.attributes_for(:invalid_contact)
    }.to_not change(Contact,:count)
  end

  it "re-renders the new method" do
    post :create, contact: Factory.attributes_for(:invalid_contact)
    response.should render_template :new
  end
end 
...

У вас может быть причина для более тщательного тестирования метода контроллера, о котором я не знаю. В этом случае не обращайте внимания на мой ответ на вопрос 2, и, надеюсь, мой другой ответ будет полезен!

3
aceofbassgreg 18 Апр 2013 в 04:39