2014-11-02 59 views
0

我有這樣的測試:RSpec的「無路由匹配」錯誤,但它們匹配

RSpec.describe RestaursController, :type => :controller do 

    context "GET /restaurs/:id" do 
    before do 
     @rest = FactoryGirl.create :restaur 
    end 

    context "resource exists" do 
     subject { get "restaurs/#{@rest.id}"} 
     it { expect(subject).to render_template(:show) } 
    end 

    context "resource doesn't exists" do 
     subject { get "restaurs/#{@rest.id + 1}" } 
     it { expect(subject).to redirect_to(:root) } 
    end 
    end 
end 

當我運行這些測試RSpec的說:

Failure/Error: subject { get "restaurs/#{@rest.id}"} 
ActionController::UrlGenerationError: 
    No route matches {:action=>"restaurs/7", :controller=>"restaurs"} 

但我認爲我的路線是確定。看看rake routes日誌

 Prefix Verb URI Pattern     Controller#Action 
    restaurs GET /restaurs(.:format)   restaurs#index 
      POST /restaurs(.:format)   restaurs#create 
new_restaur GET /restaurs/new(.:format)  restaurs#new 
edit_restaur GET /restaurs/:id/edit(.:format) restaurs#edit 
    restaur GET /restaurs/:id(.:format)  restaurs#show 
      PATCH /restaurs/:id(.:format)  restaurs#update 
      PUT /restaurs/:id(.:format)  restaurs#update 
      DELETE /restaurs/:id(.:format)  restaurs#destroy 
     root GET /       restaurs#index 

你有什麼想法嗎?問題是什麼?也許這是關於RSpec語法或類似的東西?

回答

2

這不是你如何在控制器測試中的動作getget的參數是動作的名稱,而不是可路由的路徑。路由不涉及測試控制器,也不是rake routes

你給它的動作名稱「餐廳/ 7」,這顯然不是你的控制器上的方法的真實名稱。相反,你應該使用get :show調用實際的方法「顯示」您的控制器上,然後傳遞的參數的散列:

get :show, id: @rest.id + 1 

同樣,你可以使用get :index,不get "/",你就可以使用get :edit, id: ...,不是get "/restaurs/#{...}/edit"。這是你想要在你的控制器上測試的實際方法,而不是一條路線是否會將你引向正確的方法。

作爲一個相關的一邊,你的開放背景是不合適的。您不應該使用GET /restaurs:/:id作爲上下文。這裏不涉及路由。只需測試方法名稱即可。