简体   繁体   中英

Rails 5 rspec no route matches on update

I'm having trouble getting this test to work. I've looked at quite a few other SO questions/answers, but they all seem to apply to older versions of Rails.

I have a controller test where I'm attempting to use my devices#update route, but I'm getting the following error:

Failures:

  1) DevicesController device#update is handled
     Failure/Error: patch :update, params: { device: @device }

     ActionController::UrlGenerationError:
       No route matches {:action=>"update", :controller=>"devices", :device=>#<Device id: 3, token: "Xn/6ut68w", nickname: "rough-snowflake-470", network: nil, ip_address: nil, gateway: nil, version: nil, ips_scan: nil, ips_exclude: nil, user_id: 3, created_at: "2018-02-21 02:44:16", updated_at: "2018-02-21 02:44:16">}

Which goes along with the following rspec test:

require 'rails_helper'

RSpec.describe DevicesController, type: :controller do

  before(:each) { @user = User.create(email: 'test@test.com', password: 'password', password_confirmation: 'password') }

  it 'device#update is handled' do
    sign_in(@user)
    @device = @user.devices.first
    patch :update, params: { device: @device }
    @device.reload
    expect(response.status).to eq(200)
  end
end

From a backend perspective, a user is created and a device is automatically created for them, I've confirmed this works through other tests.

devices_controller.rb looks like:

class DevicesController < ApplicationController
  before_action :set_device, only: %i[edit show update]
  respond_to :html

  def update
    if @device.update(device_params)
      flash[:notice] = 'Successful update'
      respond_with :edit, :device
    else
      flash[:warning] = 'Address formats allowed: x.x.x.x OR x.x.x.x-x OR x.x.x.x/x'
      respond_with :edit, :device
    end
  end

  private def set_device
    @device = Device.find(params[:id])
  end

  private def device_params
    params.require(:device).permit(:token, :nickname, :ips_scan, :ips_exclude)
  end
end

At this point, I'm just trying to get the test to work, but I really want to inject data in the params field for the test to verify the update actually works, such as this:

patch :update, params: { device: @device, nickname: 'foobar' }

Which just allows the user add a nickname to the device.

There is a route, so from what I've gathered, I'm not calling the patch :update correctly in the rspec test:

$ rake routes
  edit_device GET    /devices/:id/edit(.:format)    devices#edit
       device GET    /devices/:id(.:format)         devices#show
              PATCH  /devices/:id(.:format)         devices#update
              PUT    /devices/:id(.:format)         devices#update

What am I missing here?!

You can check your test output by running tail -f log/test.log , but I'd wager you've got a parameter issue here. Try something like this:

patch :update, params: {
    id: @device.id, device: { nickname: 'foobar' }
}

You've gotta bend to StrongParameters .

for me the following worked:

patch device_path(@device), params: { 
  device: { nickname:"foobar"}
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM