I'm looking to write a unit test for one of the methods of a controller which is as follows:
def update
@key = current_user.keys.find_by_key(params[:id])
@key.update_attributes(key_params)
redirect_to :back
end
private
def key_params
params.require(:key).permit(:note)
end
the route for this is:
PUT /projects/:project_id/keys/:id keys#update
So far I have the following:
describe '#update' do
before :each do
@user = FactoryGirl.create(:user)
@project= FactoryGirl.create(:project, user: @user)
@key = FactoryGirl.create(:key, id: 40, project: @project, user: @user)
controller.stub(:current_user).and_return(@user)
end
it 'update key' do
put :update, project_id:@project.id, id:@key.id
expect(response.code).to eq "302"
end
end
But this gives an error as follows:
KeysController#update update key
Failure/Error: put :update, project_id:@project.id, id:@key.id
ActionController::ParameterMissing:
param is missing or the value is empty: key
Any leads would be very helpful. Thanks
You need to pass key params to the action. And it is good idea to check not only response status, but action result too
it 'updates key' do
# supposing that "note" is a string column
expect do
put :update, project_id: @project.id, id: @key.id, key: { note: 'New note' }
end.to change { @key.note }.from('Old note').to('New note')
expect(response.code).to eq "302"
end
UPDATE:
In the controller you're trying to find key instance by key attribute
@key = current_user.keys.find_by_key(params[:id])
but you're passing key.id in specs. How it works in the app? I suppose, you pass a key as :id
parameter, so it should be
put :update, project_id: @project.id, id: @key.key, key: { note: 'New note' }
in your specs. Also, find_by_key
doesn't raise error if it can't find anything, it just returns nil. It means that you'll not get RecordNotFound. Moreover, it is a deprecated method, you should use find_by(key: params[:id])
To raise error use bang method find_by!(key: params[:id])
If you're passing key.id
in the app you need to make changes in the controller action
@key = current_user.keys.find(params[:id])