代码之家  ›  专栏  ›  技术社区  ›  Godzilla74

Rails 5 rspec更新时没有路由匹配

  •  4
  • Godzilla74  · 技术社区  · 7 年前

    我很难让这个测试正常进行。我已经查看了许多其他SO问题/答案,但它们似乎都适用于较旧版本的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\u 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
    

    从后端的角度来看,将创建一个用户 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' }
    

    它只允许用户向设备添加昵称。

    这是一条路线,所以从我收集的信息来看,我不会把 patch :update 在rspec测试中正确:

    $ 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
    

    我错过了什么?!

    2 回复  |  直到 7 年前
        1
  •  2
  •   t56k    7 年前

    您可以通过运行 tail -f log/test.log ,但我敢打赌这里有一个参数问题。尝试以下操作:

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

    你必须屈服于 StrongParameters .

        2
  •  0
  •   Sujeev    5 年前

    对我来说,以下措施奏效了:

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