问题
There are only two actions accessible in the ProductsController
:
# /config/routes.rb
RailsApp::Application.routes.draw do
resources :products, only: [:index, :show]
end
Tests are set up accordingly:
# /spec/controllers/products_controller_spec.rb
require 'spec_helper'
describe ProductsController do
before do
@product = Product.gen
end
describe "GET index" do
it "renders the index template" do
get :index
expect(response.status).to eq(200)
expect(response).to render_template(:index)
end
end
describe "GET show" do
it "renders the show template" do
get :show, id: @product.id
expect(response.status).to eq(200)
expect(response).to render_template(:show)
end
end
end
How would you test that the other CRUD actions are not accessible? This might change in the future so the tests will ensure any configuration change will be noticed.
I found the be_routable matcher which looks promising to cover the test case.
I recommend this post by Dave Newton which describes when and why to test controller actions.
回答1:
Here is what I came up with:
context "as any user" do
describe "not routable actions" do
it "rejects routing for :new" do
expect(get: "/products/new").not_to be_routable
end
it "rejects routing for :create" do
expect(post: "/products").not_to be_routable
end
it "rejects routing for :edit" do
expect(get: "/products/#{@product.id}/edit").not_to be_routable
end
it "rejects routing for :update" do
expect(put: "/products/#{@product.id}").not_to be_routable
end
it "rejects routing for :destroy" do
expect(delete: "/products/#{@product.id}").not_to be_routable
end
end
end
However one test fails:
Failure/Error: expect(get: "/products/new").not_to be_routable
expected {:get=>"/products/new"} not to be routable,
but it routes to {:action=>"show", :controller=>"products", :id=>"new"}
Please feel free to add your own solution if you follow a totally different approach to test non-existing routes.
来源:https://stackoverflow.com/questions/18357389/how-to-test-a-controller-action-that-does-not-exist