I am using rails 5.0.0.1 to build a small inventory type system for some equipment I lone to people. One of my models is named equipment which of course is an uncountable model (singular and plural of equipment is the same). When I try to write feature tests for this model I get one of two possible errors when I try to visit the index page. If I use "visit equipment_url" I am told there is no route for "show" because there is no id. This is a correct error if I wanted to go to show but I don't. If I try "visit equipment_index_url" I am told there is no method visit.
Routes
Prefix Verb URI Pattern Controller#Action
root GET / inventory#index
delete_equipment GET /equipment/:id/delete(.:format) equipment#delete
DELETE /equipment/:id/delete(.:format) equipment#destroy
equipment_index GET /equipment(.:format) equipment#index
POST /equipment(.:format) equipment#create
new_equipment GET /equipment/new(.:format) equipment#new
edit_equipment GET /equipment/:id/edit(.:format) equipment#edit
equipment GET /equipment/:id(.:format) equipment#show
PATCH /equipment/:id(.:format) equipment#update
PUT /equipment/:id(.:format) equipment#update
DELETE /equipment/:id(.:format) equipment#destroy
delete_specialty GET /specialties/:id/delete(.:format) specialties#delete
DELETE /specialties/:id/delete(.:format) specialties#destroy
specialties GET /specialties(.:format) specialties#index
POST /specialties(.:format) specialties#create
new_specialty GET /specialties/new(.:format) specialties#new
edit_specialty GET /specialties/:id/edit(.:format) specialties#edit
specialty GET /specialties/:id(.:format) specialties#show
PATCH /specialties/:id(.:format) specialties#update
PUT /specialties/:id(.:format) specialties#update
DELETE /specialties/:id(.:format) specialties#destroy
delete_event GET /events/:id/delete(.:format) events#delete
DELETE /events/:id/delete(.:format) events#destroy
events GET /events(.:format) events#index
POST /events(.:format) events#create
new_event GET /events/new(.:format) events#new
edit_event GET /events/:id/edit(.:format) events#edit
event GET /events/:id(.:format) events#show
PATCH /events/:id(.:format) events#update
PUT /events/:id(.:format) events#update
DELETE /events/:id(.:format) events#destroy
delete_type GET /types/:id/delete(.:format) types#delete
DELETE /types/:id/delete(.:format) types#destroy
types GET /types(.:format) types#index
POST /types(.:format) types#create
new_type GET /types/new(.:format) types#new
edit_type GET /types/:id/edit(.:format) types#edit
type GET /types/:id(.:format) types#show
PATCH /types/:id(.:format) types#update
PUT /types/:id(.:format) types#update
DELETE /types/:id(.:format) types#destroy
delete_event_specialty GET /event_specialties/:id/delete(.:format) event_specialties#delete
DELETE /event_specialties/:id/delete(.:format) event_specialties#destroy
event_specialties GET /event_specialties(.:format) event_specialties#index
POST /event_specialties(.:format) event_specialties#create
new_event_specialty GET /event_specialties/new(.:format) event_specialties#new
edit_event_specialty GET /event_specialties/:id/edit(.:format) event_specialties#edit
event_specialty GET /event_specialties/:id(.:format) event_specialties#show
PATCH /event_specialties/:id(.:format) event_specialties#update
PUT /event_specialties/:id(.:format) event_specialties#update
DELETE /event_specialties/:id(.:format) event_specialties#destroy
spec/features/equipment_spec.rb
require 'rails_helper'
RSpec.describe "Equipment", type: :request do
describe "GET /equipment" do
it "Adds a new equipment" do
#types = FactoryGirl.create_list(:multitype, 25)
#specialties = FactoryGirl.create_list(:multispecialty, 25)
visit equipment_index_url
expect{
click_link 'New Equipment'
fill_in "Equipment No", with: "2"
fill_in "Serial", with: "123456"
fill_in "Description", with: "Test Equipment"
select "radio10", from: "equipment_type_id"
select "tech13", from: "equipment_specialty_id"
click_button "Create Equipment"
}.to change(Equipment, :count).by(1)
expect(page).to have_content("Equipment was successfully created")
end
it "deletes without javascript" do
equipment = FactoryGirl.create(:equipment)
visit equipment_url
expect {
click_link "Destroy"
}.to change(Equipment, :count).by(-1)
expect(page).to have_content("Equipment was successfully destroyed")
end
it "edits a equipment" do
equipment = FactoryGirl.create(:equipment)
visit equipment_url
click_link 'Edit'
fill_in "Serial", with: "456789"
click_button "Update Equipment"
expect(page).to have_content("Equipment was successfully updated")
expect(page).to have_content("Serial: 456789")
end
it "shows a equipment" do
equipment = FactoryGirl.create(:equipment)
visit equipment_url
click_link 'Show'
expect(page).to have_content("Serial: rad123")
expect(page).to have_link("Edit")
expect(page).to have_link("Back", href: equipment_path)
end
end
end
Errors
Equipment
GET /equipment
Adds a new equipment (FAILED - 1)
deletes without javascript (FAILED - 2)
edits a equipment (FAILED - 3)
shows a equipment (FAILED - 4)
Failures:
1) Equipment GET /equipment Adds a new equipment
Failure/Error: visit equipment_index_url
NoMethodError:
undefined method `visit' for #<RSpec::ExampleGroups::Equipment::GETEquipment:0x000000065c32e8>
# ./spec/features/equipment_spec.rb:8:in `block (3 levels) in <top (required)>'
# /home/tom/.rvm/gems/ruby-2.3.1#rails5.0/gems/rspec-retry-0.5.2/lib/rspec/retry.rb:112:in `block in run'
# /home/tom/.rvm/gems/ruby-2.3.1#rails5.0/gems/rspec-retry-0.5.2/lib/rspec/retry.rb:101:in `loop'
# /home/tom/.rvm/gems/ruby-2.3.1#rails5.0/gems/rspec-retry-0.5.2/lib/rspec/retry.rb:101:in `run'
# /home/tom/.rvm/gems/ruby-2.3.1#rails5.0/gems/rspec-retry-0.5.2/lib/rspec_ext/rspec_ext.rb:12:in `run_with_retry'
# /home/tom/.rvm/gems/ruby-2.3.1#rails5.0/gems/rspec-retry-0.5.2/lib/rspec/retry.rb:30:in `block (2 levels) in setup'
2) Equipment GET /equipment deletes without javascript
Failure/Error: visit equipment_url
ActionController::UrlGenerationError:
No route matches {:action=>"show", :controller=>"equipment"} missing required keys: [:id]
# ./spec/features/equipment_spec.rb:23:in `block (3 levels) in <top (required)>'
# /home/tom/.rvm/gems/ruby-2.3.1#rails5.0/gems/rspec-retry-0.5.2/lib/rspec/retry.rb:112:in `block in run'
# /home/tom/.rvm/gems/ruby-2.3.1#rails5.0/gems/rspec-retry-0.5.2/lib/rspec/retry.rb:101:in `loop'
# /home/tom/.rvm/gems/ruby-2.3.1#rails5.0/gems/rspec-retry-0.5.2/lib/rspec/retry.rb:101:in `run'
# /home/tom/.rvm/gems/ruby-2.3.1#rails5.0/gems/rspec-retry-0.5.2/lib/rspec_ext/rspec_ext.rb:12:in `run_with_retry'
# /home/tom/.rvm/gems/ruby-2.3.1#rails5.0/gems/rspec-retry-0.5.2/lib/rspec/retry.rb:30:in `block (2 levels) in setup'
3) Equipment GET /equipment edits a equipment
Failure/Error: visit equipment_url
ActionController::UrlGenerationError:
No route matches {:action=>"show", :controller=>"equipment"} missing required keys: [:id]
# ./spec/features/equipment_spec.rb:32:in `block (3 levels) in <top (required)>'
# /home/tom/.rvm/gems/ruby-2.3.1#rails5.0/gems/rspec-retry-0.5.2/lib/rspec/retry.rb:112:in `block in run'
# /home/tom/.rvm/gems/ruby-2.3.1#rails5.0/gems/rspec-retry-0.5.2/lib/rspec/retry.rb:101:in `loop'
# /home/tom/.rvm/gems/ruby-2.3.1#rails5.0/gems/rspec-retry-0.5.2/lib/rspec/retry.rb:101:in `run'
# /home/tom/.rvm/gems/ruby-2.3.1#rails5.0/gems/rspec-retry-0.5.2/lib/rspec_ext/rspec_ext.rb:12:in `run_with_retry'
# /home/tom/.rvm/gems/ruby-2.3.1#rails5.0/gems/rspec-retry-0.5.2/lib/rspec/retry.rb:30:in `block (2 levels) in setup'
4) Equipment GET /equipment shows a equipment
Failure/Error: visit equipment_url
ActionController::UrlGenerationError:
No route matches {:action=>"show", :controller=>"equipment"} missing required keys: [:id]
# ./spec/features/equipment_spec.rb:42:in `block (3 levels) in <top (required)>'
# /home/tom/.rvm/gems/ruby-2.3.1#rails5.0/gems/rspec-retry-0.5.2/lib/rspec/retry.rb:112:in `block in run'
# /home/tom/.rvm/gems/ruby-2.3.1#rails5.0/gems/rspec-retry-0.5.2/lib/rspec/retry.rb:101:in `loop'
# /home/tom/.rvm/gems/ruby-2.3.1#rails5.0/gems/rspec-retry-0.5.2/lib/rspec/retry.rb:101:in `run'
# /home/tom/.rvm/gems/ruby-2.3.1#rails5.0/gems/rspec-retry-0.5.2/lib/rspec_ext/rspec_ext.rb:12:in `run_with_retry'
# /home/tom/.rvm/gems/ruby-2.3.1#rails5.0/gems/rspec-retry-0.5.2/lib/rspec/retry.rb:30:in `block (2 levels) in setup'
Finished in 0.28107 seconds (files took 2.61 seconds to load)
4 examples, 4 failures
Failed examples:
rspec ./spec/features/equipment_spec.rb:5 # Equipment GET /equipment Adds a new equipment
rspec ./spec/features/equipment_spec.rb:21 # Equipment GET /equipment deletes without javascript
rspec ./spec/features/equipment_spec.rb:30 # Equipment GET /equipment edits a equipment
rspec ./spec/features/equipment_spec.rb:40 # Equipment GET /equipment shows a equipment
Any Ideas on how to make it work would be greatly appreciated
I believe that the "RSpec.describe "Equipment", type: :request" has to be type ":feature" for capybara testing to work properly.
This should fix the show errors, because I assume it doesn't have an ID because it is not visiting equipment_url correctly. If that isn't the problem, then equipment#show is not receiving an instance variable.
Related
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
Ok so I want to create a test for checking that all pages have a certain title. However I thought it would be nice if I could include the page titles in an array so that I wouldn't have to duplicate the block for each page. And it would allow me to test additional pages by just modifying the pages array.
The issue I am having is that the page variable is not being interpolated in the test. So is this a syntax error or does Rspec not allow interpolation within the it should do... block?
describe "LayoutLinks" do
page = ["home", "contact", "about", "help"]
i = page.count
x = 0
while x < i
it "should have a #{page[x]} page" do
get "#{page[x]}"
response.should have_selector("title", :content => "#{page[x]}")
end
x += 1
end
end
Test shows the following failures:
1) PagesController LayoutLinks should have a help page
Failure/Error: get "#{page[x]}"
ActionController::RoutingError:
No route matches {:controller=>"pages", :action=>""}
# ./spec/controllers/layout_links_spec.rb:14:in `block (3 levels) in <top (required)>'
2) PagesController LayoutLinks should have a contact page
Failure/Error: get "#{page[x]}"
ActionController::RoutingError:
No route matches {:controller=>"pages", :action=>""}
# ./spec/controllers/layout_links_spec.rb:14:in `block (3 levels) in <top (required)>'
3) PagesController LayoutLinks should have a about page
Failure/Error: get "#{page[x]}"
ActionController::RoutingError:
No route matches {:controller=>"pages", :action=>""}
# ./spec/controllers/layout_links_spec.rb:14:in `block (3 levels) in <top (required)>'
4) PagesController LayoutLinks should have a home page
Failure/Error: get "#{page[x]}"
ActionController::RoutingError:
No route matches {:controller=>"pages", :action=>""}
Failure error here is obvious. It shouldn't say get "#{page[x]}" but rather it should be get home and get about, etc...
How do I remedy? Thanks for the help. Much appreciated :)
Try the following:
describe "LayoutLinks" do
%w(home contact about help).each do |page|
it "should have a #{page} page" do
get page
response.should have_selector("title", content: page)
end
end
end
%w creates an array of strings (spaces become commas, so you get ["home", "contact", etc])
Trying to get my title test to pass and see this error when running:
bundle exec rspec spec/requests/static_pages_spec.rb
Failures:
1) Static pages Help page should have the h1 'Help'
Failure/Error: visit '/static_pages/Help'
ActionController::RoutingError:
No route matches [GET] "/static_pages/Help"
# ./spec/requests/static_pages_spec.rb:19:in `block (3 levels) in <top (required)>'
2) Static pages Help page should have the title 'Help'
Failure/Error: visit '/static_pages/Help'
ActionController::RoutingError:
No route matches [GET] "/static_pages/Help"
# ./spec/requests/static_pages_spec.rb:24:in `block (3 levels) in <top (required)>'
3) Static pages About page should have the h1 'About Us'
Failure/Error: visit '/static_pages/About'
ActionController::RoutingError:
No route matches [GET] "/static_pages/About"
# ./spec/requests/static_pages_spec.rb:31:in `block (3 levels) in <top (required)>'
4) Static pages About page should have the title 'About Us'
Failure/Error: visit '/static_pages/About'
ActionController::RoutingError:
No route matches [GET] "/static_pages/About"
# ./spec/requests/static_pages_spec.rb:36:in `block (3 levels) in <top (required)>'
Finished in 0.16042 seconds
6 examples, 4 failures
Failed examples:
rspec ./spec/requests/static_pages_spec.rb:18 # Static pages Help page should have the h1 'Help'
rspec ./spec/requests/static_pages_spec.rb:23 # Static pages Help page should have the title 'Help'
rspec ./spec/requests/static_pages_spec.rb:30 # Static pages About page should have the h1 'About Us'
rspec ./spec/requests/static_pages_spec.rb:35 # Static pages About page should have the title 'About Us'
SampleApp::Application.routes.draw do
get "static_pages/home"
get "static_pages/help"
get "static_pages/about"
I've tried various answers already posted in other threads and haven't been successful. Any help would be much appreciated.
Your URLs should be '/static_pages/help' instead of '/static_pages/Help'.
I have a location resource and access via:
http://localhost:3000/locations/37/edit
In my spec, I have:
it "should allows us to edit" do
#u=User.find_by_email('jon#domain.com')
session[:user_id]=#u.id
get edit_location_path, {:id => '37'}
but get the following error:
Failures:
1) LocationsController should allows us to edit
Failure/Error: get edit_location_path, :id => '37'
ActionController::RoutingError:
No route matches {:action=>"edit", :controller=>"locations"}
# ./spec/controllers/locations_controller_spec.rb:12:in `block (2 levels) in <top (required)>'
How would I specify the link to this resource?
thx
Assuming it's a controller spec describing LocationsController, you can access it with get :edit, :id => 37.
Just do get edit_location_path(37) ??
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.