Rails 4 で単純なコントローラーをテストするために factory_girl_rails (4.2.1) と rspec-rails (2.14.0) を使用しています。エラー ケースをテストするときにFactoryGirl.build
、無効なUser
オブジェクトを作成していました。ただし、結果のオブジェクトにはエラーは含まれていません@user.errors
。まだexpect(assigns(:user)).to have(1).errors_on(:email)
テストケースでは合格しています。FactoryGirl で生成されたオブジェクトにエラーがないのはなぜですか? rspec はエラーをどのように認識しますか?
詳細とコードはこちら。
コントローラーは単純に User オブジェクトを作成し、作成が成功した場合は検証ページにリダイレクトし、エラーが発生した場合はフォームを再度レンダリングします。
class RegistrationController < ApplicationController
def new
end
def create
@user = User.create(params.required(:user).permit(:email, :password, :password_confirmation))
if @user.errors.empty?
redirect_to verify_registration_path
else
render :new
end
end
end
私のエラー ケース テストでは、User
FactoryGirl を使用して「メール」なしで を作成しました。@user.errors
「email」フィールドにエラー エントリを作成し、:new テンプレートをレンダリングすることが期待されます。
describe RegistrationController do
#... Some other examples ...
describe 'GET create' do
def post_create(user_params)
allow(User).to receive(:create).with(ActionController::Parameters.new({user: user_params})[:user]).and_return(FactoryGirl.build(:user, user_params))
post :create, user: user_params
end
context 'without email' do
before { post_create email: '', password: 'testing', password_confirmation: 'testing' }
subject { assigns(:user) }
it 'build the User with error' do
expect(subject).to have(1).errors_on(:email)
end
it 'renders the registration form' do
expect(response).to render_template('new')
end
end
end
end
ただし、テスト ケースを実行すると、例のみが'renders the registration form'
失敗し、他の例は失敗しませんでした。
Failures:
1) RegistrationController GET create without email renders the registration form
Failure/Error: expect(response).to render_template('new')
expecting <"new"> but rendering with <[]>
# ./spec/controllers/registration_controller_spec.rb:51:in `block (4 levels) in <top (required)>'
Finished in 0.25726 seconds
6 examples, 1 failure
Failed examples:
rspec ./spec/controllers/registration_controller_spec.rb:50 # RegistrationController GET create without email renders the registration form
ここで奇妙なのは、rspec でエラーを確認できるように見える@user
(したがって、最初のテスト ケースはパスする) が、なんらかの不明な理由でコントローラーが@user.error.empty?
返され、テンプレートtrue
をレンダリングする代わりにリダイレクトされる(したがって、2 番目のテスト ケースが失敗する) ことです。また、実際に空:new
であることをデバッガーで確認しました。@user.error
FactoryGirl がエラーを処理する方法に問題がありますか、それとも間違って使用していますか?
ありがとう