RSpec“无路由匹配”错误但它们匹配

时间:2014-11-02 19:18:07

标签: ruby-on-rails 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语法或类似的东西?

1 个答案:

答案 0 :(得分:2)

这不是您在控制器测试中get操作的方式。 get的参数是操作的名称,而不是可路由的路径。测试控制器不涉及路由,rake routes也没有。

你给它的是动作名称“restaurs / 7”,这显然不是控制器上方法的真实名称。相反,您应该使用get :show在控制器上调用实际方法“show”,然后传递参数哈希:

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

同样,您可以使用get :index,而不是get "/",并使用get :edit, id: ...,而不是get "/restaurs/#{...}/edit"。这是您在控制器上测试的实际方法,而不是路线是否真正引导您使用正确的方法。

相反,您的开放背景不合适。您不应该使用GET /restaurs:/:id作为上下文。此处不涉及路由。只需测试方法名称。