我写了这段代码来测试控制器更新功能。 写了一种消除重复代码的方法。 这是一种明确的方法吗?
users_controller_spec.rb
context 'Update failed' do
def render_edit
user.reload
expect(response.status).to eq(200)
end
it 'Name is nil' do
put :update, params: { id: user.id, user: { name: '' } }
render_edit
end
it 'Email is exist' do
create(:user, email: 'user@gmail.com')
put :update, params: { id: user.id, user: { email: 'user@gmail.com' } }
render_edit
end
it 'Email is nil' do
put :update, params: { id: user.id, user: { email: '' } }
render_edit
end
it 'Password must be at least 8 characters' do
put :update, params: { id: user.id, user: { password: '1234567', password_confirmation: '1234567' } }
render_edit
end
it 'Passwords do not match' do
put :update, params: { id: user.id, user: { password: '1234567890', password_confirmation: '123456789' } }
render_edit
end
end
我当时正在考虑使用after(:each)。但是看起来有点逻辑上的联系。 或使用循环替换参数。
有什么建议吗?
答案 0 :(得分:1)
您可以使用注释中建议的共享示例,但是有一种更简单的方法。
context 'Update failed' do
before do
put :update, params: params
user.reload # I'm not sure why you need this
end
subject { response }
context 'Name is nil' do
let(:params} { {id: user.id, user: { name: '' }} }
it { is_expected.to be_success }
end
context 'Email exists' do
let(:params) { { id: user.id, user: { email: 'user@gmail.com' } }
let(:user) { create(:user, email: 'user@gmail.com') }
it { is_expected.to be_success }
end
# and so on
end
我使用的主要符文是-使每种情况下的变化显而易见。因此,与其重新定义put ...
,不如将其提取为let并根据上下文进行定义。
be_success
是rspec魔术的一部分,无论您在哪里使用be_something
匹配器,它都会尝试使用something?
方法并检查其是否正确,即。
expect(foo).to be_empty?
== expect(foo.empty?).to eq(true)
如果您不希望这样的话
subject { response.status }
# and later
is_expected.to eq 200
is_expected.to
仅仅是expect(subject).to