RSpec игнорирует attr_accessor? - PullRequest
0 голосов
/ 04 марта 2011

Я настроил модель User AR с условной проверкой, которая в значительной степени идентична эпизоду Railscast при условной проверке. В общем, моя модель User выглядит так:

class User < ActiveRecord::Base
  attr_accessor :password, :updating_password

   validates :password, :presence => true,
             :confirmation => true,
             :length => { :within => 6..40 },
             :if => :should_validate_password?

  def should_validate_password?
    updating_password || new_record?
  end
end

Теперь в моем действии, где Пользователь может изменить свой пароль, у меня есть следующие две строки:

@user.updating_password = true
if @user.update_attributes(params[:user]) ...

чтобы я отмечал проверки для пароля. В режиме разработки это прекрасно работает - если пользователь пытается ввести слишком короткий или слишком длинный пароль, модель не проходит проверку. Моя проблема в том, что из-за жизни я не могу сдать свои тесты на это. Вот моя спецификация:

require 'spec_helper'

 describe PasswordsController do
   render_views

   before(:each) do
     @user = Factory(:user)
   end

   describe "PUT 'update'" do

     describe "validations" do

     before(:each) do
       test_sign_in(@user)
     end

       it "should reject short passwords" do
         short = "short"
         old_password = @user.password
         @attr2 = { :password => short, :password_confirmation => short }
         put :update, :user_id => @user, :old_password => @user.password, :user => @attr2
         @user.password.should == old_password
       end

       it "should reject long passwords" do
         long = "a" * 41
         old_password = @user.password
         @attr2 = { :password => long, :password_confirmation => long }
         put :update, :user_id => @user, :old_password => @user.password, :user => @attr2
         @user.password.should == old_password
       end
      end
     end
    end

Когда я запускаю эти тесты, я всегда получаю сообщение об ошибке:

1) PasswordsController PUT 'update' validations should reject short passwords
 Failure/Error: @user.password.should == old_password2
   expected: "foobar"
        got: "short" (using ==)

и, конечно, ошибка для пароля слишком длинная. Но должен ли пароль быть проверен в результате того, что я установил @user.updating_password = true перед любыми попытками сохранения в контроллере?

1 Ответ

1 голос
/ 04 марта 2011

Я думаю, что проблема не в коде, а в том, что вы ожидаете от него. Когда вы вызываете update_attributes и передаете неверное значение, значение сохраняется в объекте модели, даже если проверка не пройдена; неверное значение не было передано в базу данных.

Я думаю, что это имеет смысл, потому что, когда валидация не проходит нормально, вы бы снова показывали форму с сообщениями об ошибках и входами, заполненными ошибочными значениями, которые были переданы. В приложении Rails эти значения обычно берутся из объекта модели обсуждаемый. Если плохие значения не были сохранены в модели, они будут потеряны, и ваша форма будет указывать, что старые «хорошие» значения не прошли проверку.

Вместо выполнения этой проверки:

@user.password.should == old_password

Может быть, попробовать:

@user.errors[:password].should_not == nil

или какой-то другой тест, который имеет смысл.

...