rspec: ActionController::UrlGenerationError, 没有路由匹配

rspec: ActionController::UrlGenerationError, No route matches

将 download_qr link 移出此 current_user.admin 之后?来自:

#plots.show.html.haml (excerpt)
- content_for_title("Plot ##{@plot.plot_id}")
- content_for(:subnav) do
  = link_to '« Plots', plots_path, class: 'btn btn-primary', title: 'List of all plots'
  - if current_user&.admin?
    = link_to 'Download QR Code', { action: 'download_qr' }, 'data-turbolinks': false, class: 'btn btn-secondary', title: "QR Code for #{@plot}"
    = link_to 'Edit', edit_plot_path(@plot), class: 'btn btn-primary', title: "Edit #{@plot}"
    = link_to 'Delete', @plot, method: :delete, data: { confirm: "Delete Plot ##{@plot.plot_id}?" }, class: 'btn-tertiary', title: "Delete #{@plot}"

对此:

- content_for_title("Plot ##{@plot.plot_id}")
- content_for(:subnav) do
  = link_to '« Plots', plots_path, class: 'btn btn-primary', title: 'List of all plots'
  = link_to 'Download QR Code', { action: 'download_qr' }, 'data-turbolinks': false, class: 'btn btn-secondary', title: "QR Code for #{@plot}"
  - if current_user&.admin?
    = link_to 'Edit', edit_plot_path(@plot), class: 'btn btn-primary', title: "Edit #{@plot}"
    = link_to 'Delete', @plot, method: :delete, data: { confirm: "Delete Plot ##{@plot.plot_id}?" }, class: 'btn-tertiary', title: "Delete #{@plot}"

我在 rspec

中收到此错误
plots/show displaying inoculation inoculated displays 'Yes'
     Failure/Error: = link_to 'Download QR Code', { action: 'download_qr' }, 'data-turbolinks': false, class: 'btn btn-secondary', title: "QR Code for #{@plot}"
     
     ActionView::Template::Error:
       No route matches {:action=>"download_qr", :controller=>"plots"}
     # ./app/views/plots/show.html.haml:4:in `block in _app_views_plots_show_html_haml__2393189060377325026_107320'
     # ./app/views/plots/show.html.haml:2:in `_app_views_plots_show_html_haml__2393189060377325026_107320'
     # ./spec/views/plots/show.html.erb_spec.rb:10:in `block (4 levels) in <top (required)>'
     # ------------------
     # --- Caused by: ---
     # ActionController::UrlGenerationError:
     #   No route matches {:action=>"download_qr", :controller=>"plots"}
     #   ./app/views/plots/show.html.haml:4:in `block in _app_views_plots_show_html_haml__2393189060377325026_107320'

这是 rails 路线的输出:

plots#index
                                         POST     /plots(.:format)                                                                                  plots#create
                                new_plot GET      /plots/new(.:format)                                                                              plots#new
                               edit_plot GET      /plots/:id/edit(.:format)                                                                         plots#edit
                                    plot GET      /plots/:id(.:format)                                                                              plots#show
                                         PATCH    /plots/:id(.:format)                                                                              plots#update
                                         PUT      /plots/:id(.:format)                                                                              plots#update
                                         DELETE   /plots/:id(.:format)                                                                              plots#destroy
                                         GET      /plots/:id/download_qr(.:format)                                                                  plots#download_qr

测试本身:

#show.html.erb_spec(excerpt)
require 'rails_helper'

RSpec.describe "plots/show", type: :view do

  describe "displaying inoculation" do

    context "inoculated" do
      it "displays 'Yes'" do
        assign(:plot, create(:plot))
        render
        expect(rendered).to have_content("Yes")
      end
    end

和规范控制器:

#plots_controller_spec(excerpt)
RSpec.describe PlotsController, type: :controller do
  let(:general_user) { FactoryBot.build(:user) }
  let(:admin_user) { FactoryBot.build(:user, :admin) }
  let(:plot) { FactoryBot.create(:plot) }
  let(:plant) { create(:plant) }
  let(:invalid_plot) { FactoryBot.build(:invalid_plot) }

  before do
    allow(controller).to receive(:current_user).and_return(admin_user)
  end

  describe '#index' do
    it 'returns http success' do
      get :index
      expect(response).to have_http_status(:success)
    end
  end

  describe '#show' do
    it 'returns http success' do
      get :show, params: { id: plot.id }
      expect(response).to have_http_status(:success)
    end
  end

该路由在实际应用中运行良好,当我将 link 移回 current_user.admin 时测试通过了?堵塞。我认为这一定与测试的路由方式有关,但我似乎无法弄清楚。

根据 rails 路由的输出,您有 member download_qr 操作。这意味着您需要指定要下载二维码的绘图实例:id /plots/:id/download_qr;有关成员和收集路线的更多信息,请参阅 Rails guides

考虑到这一点,您需要将 :id 参数添加到您的 link_to as

= link_to 'Download QR Code', { controller: 'plots', action: 'download_qr', id: @plot }, class: 'btn btn-primary' ... 

您可以在 link_to 选项中找到更多有价值的示例 here

我可以假设您的测试通过了,并且当 link 在 current_user&.admin? 块的范围内时应用程序运行正常,因为您在没有当前用户或 [=30] 的情况下检查了它=] 用户。条件被评估为假;视图的相应部分根本不会 rendered/called。