我正在使用factory_girl_rails(4.2.1)和rspec-rails(2.14.0)来测试Rails 4上的一个简单控制器。在测试错误情况时,我使用FactoryGirl.build
来构建一个无效的{{1对象。但是,生成的对象在User
中不包含任何错误;但测试用例中的@user.errors
仍然通过。为什么FactoryGirl生成的对象没有任何错误,rspec如何查看错误?
以下是详细信息和代码。
控制器只是创建一个User对象,然后在创建成功时重定向到验证页面,或者如果有任何错误则再次渲染表单。
expect(assigns(:user)).to have(1).errors_on(:email)
在我的错误案例测试中,我使用FactoryGirl创建了一个没有'email'的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
中为“电子邮件”字段创建错误条目,并呈现:新模板。
@user.errors
但是,当我运行测试用例时,只有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'
这里奇怪的是,rspec似乎能够在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
中看到错误(因此第一个测试用例通过)但由于某些未知原因@user
在控制器中返回@user.error.empty?
导致它重定向而不是渲染true
模板(因此失败的第二个测试用例)。我还在调试器中确认:new
确实是空的。
FactoryGirl处理错误的方式有问题,或者我使用错误了吗?
由于
答案 0 :(得分:0)
我想在此提及的两件事是:
1.可能你想使用“创建后”而不是“获取创造”
2.电子邮件是否丢失是模型的关注点,而不是控制器的问题
我建议您使用stub来返回false,因为电子邮件丢失了。
最简单的方法是:
User.any_instance.stub(:create).and_return(false)
也许你想改变控制器中的其他东西,比如“if @ user.errors.empty?”
编辑:抱歉,“创建”实际上不会返回错误。
所以在你的控制器中
@user = User.new(.....)
if @user.save
...
else
render :new
在你的测试中使用
User.any_instance.stub(:save).and_return(false)