Techioz Blog

「文字列からハッシュへの暗黙的な変換が行われない」を修正する方法

概要

RSpec でテストを実行しようとしていますが、常に同じエラーが返されます。

DevicesController#update when user is a manager must update any device
     Failure/Error: put device_path device_id, params: params, headers: { 'Content-Type': 'application/vnd.api+json' }

     TypeError:
       no implicit conversion of String into Hash

リクエストパラメータを使用した私の関数:

def update_params(device, device_id)
  {
    data: {
      id: device.id,
      type: 'device',
      attributes: {
        device_id: device_id 
      }
    }
  }.to_json
end

ファクトリを使用した私のテスト:

context 'when user is a manager' do
  let(:user) { create(:manager).account }
  let(:firebase_token) { Faker::Crypto.sha1 }
  let(:device_id) { physical_device.id }
  let(:params) { update_params(physical_device, firebase_token) }
  it 'must update any device' do
    expect(Device.find(device_id).device_id).to eq(firebase_token)
  end
end

リクエストの OS アップデート デバイス:

put device_path device_id, params: params, headers: { 'Content-Type': 'application/vnd.api+json' }

解決策

ActionController::TestCase は、パラメータが (ヘッダーと同様に) ハッシュであることを期待します。

ただし、このメソッド呼び出しに渡すパラメータは

put device_path device_id, params: params, headers: { 'Content-Type': 'application/vnd.api+json' }

これらは update_params メソッドによって生成され、そのメソッドは生成されたハッシュに対して to_json を呼び出すため、JSON 文字列を返します。

update_params メソッドの最後の行から .to_json を削除するだけで問題ありません。