How to deal with RoutingError while testing with Rspec? - ruby-on-rails

I created a controller called PolicyController and nested its route like this:
scope "/your"
resources :shops do
resources :policies
end
end
Now when I'm trying to test this controller I keep getting this error:
1) PoliciesController POST 'create' should be successful
Failure/Error: post 'create'
ActionController::RoutingError:
No route matches {:controller=>"policies", :action=>"create"}
# ./spec/controllers/policies_controller_spec.rb:7:in `block (3 levels) in <top (required)>'
Not sure how to set it right. Would appreciate the help.
Edit: Forgot my specs:
describe PoliciesController do
describe "POST 'create'" do
it "should be successful" do
post 'create'
response.should be_success
end
end

Do you think this will work?
post :create, :shop_id => 1
Definitely want to create a new shop in a before block.

Related

Rails units testing: No route matches why?

I'm trying to do some units test, this is my first time.
I don't really understand why there is No route matches.
When i run $ rake test test/controllers/products_controller_test.rb
i get this in the output of the console:
1) Error:
ProductsControllerTest#test_should_get_edit:
ActionController::UrlGenerationError: No route matches {:action=>"edit", :controller=>"products"}
test/controllers/products_controller_test.rb:20:in `block in <class:ProductsControllerTest>'
2) Error:
ProductsControllerTest#test_should_get_show:
ActionController::UrlGenerationError: No route matches {:action=>"show", :controller=>"products"}
test/controllers/products_controller_test.rb:35:in `block in <class:ProductsControllerTest>'
3) Error:
ProductsControllerTest#test_should_get_create:
ActionController::ParameterMissing: param is missing or the value is empty: product
app/controllers/products_controller.rb:59:in 'product_params'
app/controllers/products_controller.rb:18:in 'create'
test/controllers/products_controller_test.rb:15:in `block in <class:ProductsControllerTest>'
4) Error:
ProductsControllerTest#test_should_get_update:
ActionController::UrlGenerationError: No route matches {:action=>"update", :controller=>"products"}
test/controllers/products_controller_test.rb:25:in `block in <class:ProductsControllerTest>'
5) Error:
ProductsControllerTest#test_should_get_destroy:
ActionController::UrlGenerationError: No route matches {:action=>"destroy", :controller=>"products"}
test/controllers/products_controller_test.rb:30:in `block in <class:ProductsControllerTest>'
7 runs, 2 assertions, 0 failures, 5 errors, 0 skips
This is the products_controller_test.rb file:
require 'test_helper'
class ProductsControllerTest < ActionController::TestCase
test "should get index" do
get :index
assert_response :success
end
test "should get new" do
get :new
assert_response :success
end
test "should get create" do
get :create
assert_response :success
end
test "should get edit" do
get :edit
assert_response :success
end
test "should get update" do
get :update
assert_response :success
end
test "should get destroy" do
get :destroy
assert_response :success
end
test "should get show" do
get :show
assert_response :success
end
end
routes.rb file:
Rails.application.routes.draw do
resources :products
end
For all these routes (edit, update, destroy), you need to say which product you're editing/updating/destroying. If Rails doesn't know it, it can't draw the route for you.
For edit, for example, the full route would be products/:product_id/edit. So Rails will need to 'fill in' the :product_id key. If you leave it blank the route breaks.
In your code, then, if you're calling get :edit, you need to specify a product id. Like so:
get :edit, product_id: products(:test_product).id
(using the fixtures explained in the Rails test tutorial here)

Rails routes, rspec

I am attempting to create a route to a controller method, in order that it pass an rpsec condition. For some reason that escapes me, RSPEC will not accept the route.
Here is the rspec:
describe BooksController do
describe 'searching AMZN' do
it 'should call the model method that performs AMZN search' do
post :search_tmdb, {:search_terms => 'hardware'}
end
My routes file reads:
Rottenpotatoes::Application.routes.draw do
resources :books
post '/books/search_amzn'
# map '/' to be a redirect to '/books'
root :to => redirect('/books')
end
The controller action in books_controller.rb:
def search_amzn
#books = Books.find_in_amzn(params[:search_terms])
end
I am clearly making an error in my route for I can't get away from this error message:
1) MoviesController searching AMZN should call the model method that performs AMZN search
Failure/Error: post :search_amzn, {:search_terms => 'hardware'}
ActionController::RoutingError:
No route matches {:search_terms=>"hardware", :controller=>"books", :action=>"search_amzn"}
# ./spec/controllers/books_controller_spec.rb:9:in `block (3 levels) in <top (required)>'
Here are links to the complete files:
Routes.rb: http://pastebin.com/yKBeLLnY
Spec: http://pastebin.com/cU3nRSvE
Change this:
post :search_tmdb, {:search_terms => 'hardware'}
to:
get :search_tmdb, {:search_terms => 'hardware'}
Also, in your routes file, change this:
post '/books/search_amzn'
to:
post '/books/search_amzn', as: :search_tmdb

How to test for routing error in rspec?

I'm simplifying a resource by removing the show action since its not needed. only listing, creating and editing are needed. I still have my SHOW test in my rspecs and its now failing (obviously since I've added an :except => [:show] to my routes file.
This is what I'm getting as a failure:
1) CampaignsController GET show assigns the requested campaign as #campaign
Failure/Error: get :show, {:id => campaign.to_param}, valid_session
ActionController::RoutingError:
No route matches {:id=>"458", :controller=>"campaigns", :action=>"show"}
# ./spec/controllers/campaigns_controller_spec.rb:49:in `block (3 levels) in <top (required)>'
2) CampaignsController routing routes to #show
Failure/Error: expect(:get => "/campaigns/1").to route_to("campaigns#show", :id => "1")
No route matches "/campaigns/1"
# ./spec/routing/campaigns_routing_spec.rb:15:in `block (3 levels) in <top (required)>'
How can I make these tests pass so that I'm expecting a routing error?
You could do
expect{ get :show }.to raise_error(ActionController::RoutingError)
See https://www.relishapp.com/rspec/rspec-expectations/v/2-0/docs/matchers/expect-error
You might also consider routing specs: https://www.relishapp.com/rspec/rspec-rails/v/2-4/docs/routing-specs
For anyone interested the Minitest equivalent would be something like:
def CampaignsControllerTest < ActionDispatch::IntegrationTest
assert_raises ActionController::RoutingError do
get "/campaigns/1"
end
end

RoutingError in Rspec

I keep running across this error for a GET request to show action.
1) ShopController GET 'show' should be successful
Failure/Error: get 'show', :id=>#shop.user.nickname
ActionController::RoutingError:
No route matches {:id=>"picardo", :controller=>"shop", :action=>"show"}
# ./spec/controllers/shop_controller_spec.rb:8:in `block (3 levels) in <top (required)>'
My routes look like this.
#routes.rb
resources :shop, :only=>[:show]
This is the controller spec:
#shop_controller_spec.rb
before(:each) do
#shop = Fabricate(:shop)
end
describe "GET 'show'" do
it "should be successful" do
get 'show', :id=>#shop.user.nickname
response.should be_success
end
end
And teh controller:
def show
#user = User.find(:first,:conditions=>{:nickname=>params[:id]})
#shop = #user.shop
end
You have to follow some rails rules.
If you have a singular resource you have to write resource :shop and if you have the plural resources you have to write resources :shops. You can run rake routes command to see the difference.
You wrote resources :shop and request sends to ShopController that is not exist in your application because I am sure that controller named ShopsController. Because the another rails rule is to name controllers in plural form and models in singular.
Or just write a controller name in routes: resources :shop, :controller => 'shops'

Rspec 2.3 on Rails 3.0.3 giving some controller access problems?

It seems a bunch of my Rspec tests now fail after moving my application to Rspec 2.3 and Rails 3.0.3
An example is here:
it "should not be able to access 'destroy'" do
delete :destroy
response.should redirect_to(signin_path)
flash[:error].should == "You must be signed in to view this page."
end
will give me the error:
1) FriendshipsController when not logged in: should not be able to access 'destroy'
Failure/Error: delete :destroy
No route matches {:controller=>"friendships", :action=>"destroy"}
# ./spec/controllers/friendships_controller_spec.rb:21:in `block (3 levels) in <top (required)>'
In my routes.rb file, I've mapped the resources for this controller...
resources :friendships
Same for
get :edit
get :show
put :update
Only one that seems to work is
post :create
But this I cannot confirm 100%.
Any thoughts? Thanks for your time!
UPDATE:
get :new
also works and my UserSessions controller (Authlogic) doesn't seem to suffer from this problem. Nothing I've done different in my UserSessions controller, model, or test that I can tell.
In the spec, try calling the method by:
delete :destroy, :id => "1"

Resources