Обеспечить сильные параметры в спецификации контроллера - PullRequest
0 голосов
/ 06 марта 2019

Я хочу написать модульный тест для одного из методов контроллера, который выглядит следующим образом:

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

маршрут для этого:

PUT              /projects/:project_id/keys/:id           keys#update

Итакпока у меня есть следующее:

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

Но это дает ошибку следующим образом:

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

Любые выводы будут очень полезны.Спасибо

1 Ответ

1 голос
/ 06 марта 2019

Вам необходимо передать ключевые параметры в действие. И это хорошая идея, чтобы проверить не только статус ответа, но и результат действия

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:

В контроллере вы пытаетесь найти экземпляр ключа по ключевому атрибуту

@key = current_user.keys.find_by_key(params[:id])

но вы передаете key.id в спецификации. Как это работает в приложении? Я полагаю, вы передаете ключ как :id параметр, поэтому он должен быть

put :update, project_id: @project.id, id: @key.key, key: { note: 'New note' } 

в ваших спецификациях. Кроме того, find_by_key не вызывает ошибку, если ничего не может найти, просто возвращает ноль. Это означает, что вы не получите RecordNotFound. Более того, это устаревший метод, вы должны использовать find_by(key: params[:id]) Чтобы вызвать ошибку, используйте метод bang find_by!(key: params[:id])

Если вы передаете key.id в приложение, вам нужно внести изменения в действие контроллера

@key = current_user.keys.find(params[:id])
...