Rails 5 rspec 更新时没有路由匹配
Rails 5 rspec no route matches on update
我无法让这个测试工作。我看过很多其他 SO questions/answers,但它们似乎都适用于 Rails.
的旧版本
我有一个控制器测试,我正在尝试使用我的 devices#update
路线,但我收到以下错误:
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">}
这与以下 rspec 测试一起进行:
需要'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
从后端 perspective,创建了一个用户,并为他们自动创建了一个 device
,我已经通过其他测试确认这有效。
devices_controller.rb
看起来像:
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
在这一点上,我只是想让测试工作,但我真的想在 params
字段中注入数据以进行测试以验证更新是否确实有效,例如:
patch :update, params: { device: @device, nickname: 'foobar' }
这只允许用户为设备添加昵称。
有一条路线,所以根据我收集到的信息,我在 rspec 测试中没有正确调用 patch :update
:
$ 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
我在这里错过了什么?!
您可以通过 运行 tail -f log/test.log
检查您的测试输出,但我敢打赌您这里遇到了参数问题。尝试这样的事情:
patch :update, params: {
id: @device.id, device: { nickname: 'foobar' }
}
你必须屈服于 StrongParameters。
对我来说,以下方法有效:
patch device_path(@device), params: {
device: { nickname:"foobar"}
}
我无法让这个测试工作。我看过很多其他 SO questions/answers,但它们似乎都适用于 Rails.
的旧版本我有一个控制器测试,我正在尝试使用我的 devices#update
路线,但我收到以下错误:
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">}
这与以下 rspec 测试一起进行:
需要'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
从后端 perspective,创建了一个用户,并为他们自动创建了一个 device
,我已经通过其他测试确认这有效。
devices_controller.rb
看起来像:
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
在这一点上,我只是想让测试工作,但我真的想在 params
字段中注入数据以进行测试以验证更新是否确实有效,例如:
patch :update, params: { device: @device, nickname: 'foobar' }
这只允许用户为设备添加昵称。
有一条路线,所以根据我收集到的信息,我在 rspec 测试中没有正确调用 patch :update
:
$ 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
我在这里错过了什么?!
您可以通过 运行 tail -f log/test.log
检查您的测试输出,但我敢打赌您这里遇到了参数问题。尝试这样的事情:
patch :update, params: {
id: @device.id, device: { nickname: 'foobar' }
}
你必须屈服于 StrongParameters。
对我来说,以下方法有效:
patch device_path(@device), params: {
device: { nickname:"foobar"}
}