簡體   English   中英

為何Rspec的Rspec No route match錯誤與Rails?

[英]Why got Rspec No route matches error with Rails?

Rails文件

應用程序/控制器/ application_controller.rb

class ApplicationController < ActionController::Base
  # ...
end

應用程序/控制器/ api_application_controller.rb

class ApiApplicationController < ActionController::API
  # ...
end

應用程序/控制器/ iot_application_controller.rb

class IotApplicationController < ApiApplicationController
  # ...
end

應用程序/控制器/ IOT / hardwares_controller.rb

class Iot::HardwaresController < IotApplicationController
  def index
    # ...
  end
end

路線

配置/ routes.rb中

Rails.application.routes.draw do
  scope module: :iot do
    resources :hardwares, only: [ :index ], constraints: { format: :json }
  end

  ...
end

檢查路線

$ rake routes
Prefix Verb  URI Pattern                    Controller#Action
...
hardwares GET  /hardwares(.:format)         iot/hardwares#index {:format=>:json}

RSpec文件

規格/控制器/ IOT / hardwares_controller.rb

require 'rails_helper'

RSpec.describe Iot::HardwaresController, type: :controller do
  describe "GET #index" do
    context "with invalid params" do
      it "renders a JSON response with errors" do
        get :index, params: { "test": 1 }
        expect(response).to have_http_status(:bad_request)
      end
    end
  end
end

錯誤

$ rspec .

Iot::HardwaresController
  GET #index
    with invalid params
      renders a JSON response with errors (FAILED - 1)

Failures:

  1) Iot::HardwaresController GET #index with invalid params renders a JSON response with errors
     Failure/Error: get :index, params: {"test": 1}

     ActionController::UrlGenerationError:
       No route matches {:action=>"index", :controller=>"iot/hardwares", :test=>1}
     # ./spec/controllers/iot/hardwares_controller.rb:17:in `block (4 levels) in <top (required)>'

Finished in 0.01547 seconds (files took 6.79 seconds to load)
1 example, 1 failure

如何在rspec中正確編寫路由?

編輯:查看提供的路由后,我認為主要問題可能是您為控制器命名空間而不是路由中的資源,如果這是問題,您將在下面找到帶有其他建議的解決方案。


確保在您的情況下在routes.rb中正確設置了路由,您應該具有以下內容:

namespace :iot do
  resources :hardwares
end

然后,您將需要在RSpec示例中的get請求中指定path而不是方法名稱:

get "/iot/hardwares", params { "test": 1 }

假設我們有一個帶index動作的BooksController 在我們的routes.rb文件中,有resources: :books

只要路由設置正確,您的示例應如下所示:

require 'rails_helper'

RSpec.describe Iot::HardwaresController, type: :controller do
  describe "GET #index" do
    context "with invalid params" do
      it "renders a JSON response with errors" do
        get "/iot/hardwares", params: { "test": 1 }
        expect(response).to have_http_status(:bad_request)
      end
    end
  end
end

為了使它更好,您可以提取路徑來讓變量,因為您可能會在更多示例中使用它。 像這樣:require'rails_helper'

RSpec.describe Iot::HardwaresController, type: :controller do
  describe "GET #index" do
    let(:path) { "/iot/hardwares" }

    context "with invalid params" do
      it "renders a JSON response with errors" do
        get path, params: { "test": 1 }
        expect(response).to have_http_status(:bad_request)
      end
    end
  end
end

您也可以考慮將規格更改為請求規格,而不是控制器規格。 在RSpec的發行說明中,您可以找到:

對於新的Rails應用程序:我們不建議將Rails-Controller-testing gem添加到您的應用程序中。 Rails團隊和RSpec核心團隊的官方建議是編寫請求規范。 請求規范使您可以專注於單個控制器操作,但是與控制器測試不同,它涉及路由器,中間件堆棧以及機架的請求和響應。 這為您正在編寫的測試增加了真實感,並有助於避免控制器規范中常見的許多問題。 在Rails 5中,由於Rails Committer團隊的Eileen Uchitelle1的工作,請求規范大大快於Rails 4中的請求規范或控制器規范。

您可以在此處了解更多信息: http : //rspec.info/blog/2016/07/rspec-3-5-has-been-released/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM