I am new Rspec and just started by generating a new controller on Rails 3. It generates some Rspec tests by default. I have a question about how to make them pass though. As it stands, I see this test in my terminal"
1) BuildingsController GET 'show'
should be successful
Failure/Error: get 'show'
No route matches {:controller=>"buildings", :action=>"show"}
# ./spec/controllers/buildings_controller_spec.rb:17:in `block (3 levels) in <top (required)>'
However, I don't understand why it's coming up because I already have this route created ("resources :buildings"), and I ran rake routes and made sure it's there.
building GET /buildings/:id(.:format) {:action=>"show", :controller=>"buildings"}
What is necessary to make this pass? Here is the test by the way:
describe "GET 'show'" do
it "should be successful" do
get 'show'
response.should be_success
end
end
You need to pass id of existing building: get :show, :id => #building.id
Routes complain about it because :id isn't optional.
Related
I have the following resource (config/routes.rb)
resources :dashboard
dashboard_index GET /dashboard(.:format) dashboard#index
POST /dashboard(.:format) dashboard#create
new_dashboard GET /dashboard/new(.:format) dashboard#new
edit_dashboard GET /dashboard/:id/edit(.:format) dashboard#edit
dashboard GET /dashboard/:id(.:format) dashboard#show
PUT /dashboard/:id(.:format) dashboard#update
DELETE /dashboard/:id(.:format) dashboard#destroy
and I have the following controller spec
require 'spec_helper'
describe DashboardController do
describe "GET 'index'" do
it "returns http success" do
get :index
response.should be_success
end
end
end
and when I run the spec I'm keep on getting the following error
Failures:
1) DashboardController GET 'index' returns http success
Failure/Error: get :index
ActionController::RoutingError:
No route matches {:controller=>"dashboard"}
# ./spec/controllers/dashboard_controller_spec.rb:7:in `block (3 levels) in <top (required)>'
Finished in 0.12126 seconds
when I check for similar questions, almost all of them are because not passing required parameters, but in my case my action does not expect a parameter, so what would be the missing part here
I'm on
gem 'rails', '3.2.9'
group :test, :development do
gem "rspec-rails", "~> 2.0"
end
thanks in advance
as #John Naegle pointed out, it appears to be a problem with my spork + guard setup and its not picking up the 'routes.rb' file
Sorry for the confusion
I'm trying to do the following in rspec (know that I shouldn't have hardcoded value) in an integration test:
get '/api/get-other-items?id=5109'
The closest I could find was: call a specific url with rspec but it selects only a single item. I have tried the following:
get :controller => 'api', :action => 'get-other-items', :id => '5109'
get 'api/get-other-items', :id => '5109'
These are giving me a bad argument(expected URI object or URI string)
If I run as
get get_other_items, :id => '5109' q
I get
undefined local variable or method `get_other_items' for #<RSpec::Core::ExampleGroup::Nested_1:0x007f938fd65590>
but the route does exist:
Mon Jan 23$ rake routes | grep get_other_items
get_other_items /api/get-other-items(.:format) {:controller=>"api", :action=>"get_other_items"}
How would I perform this simple get?
thx
update for answer 1 comment
here's the rspec code in question:
it "testing getting other items for menu item" do
get get_other_items_path(:id => '5109')
JSON.parse(response.body)
puts response.body
Mon Jan 23$ rspec requests/get_other_items_spec.rb
F
Failures:
1) GetOtherItems testing getting other items for menu item
Failure/Error: JSON.parse(response.body)
JSON::ParserError:
743: unexpected token at 'this is not found '
# ./requests/get_other_items_spec.rb:19:in `block (2 levels) in <top (required)>'
Finished in 13.57 seconds
1 example, 1 failure
Failed examples:
The call should be get get_other_items_path(:id => 5109) - you need to add path to the name of the route, or url if you want the full URL instead of a relative path.
Your route doesn't look like it's taking a :id as a parameter, if you want to send an :id I would expect to see the following:
get_other_items /api/get-other-items/:id(.:format) {:controller=>"api", :action=>"get_other_items"}
Given the structure of your generated route I assume that you are using match to define the route (There is no HTTP verb in your route). To fix it try:
match 'api/get-other-items/:id' => 'api#get_other_items'
If instead you are using restful routes then it looks like you have specified a collection route rather than a member route. A collection route doesn't take an :id and is designed to return many records of the type you have specified. To make it a member route use the following:
resources :api do
get 'get_other_items', :on => :member
end
Once you get this working you should be able to try the following in rspec in your ApiController spec:
get :get_other_items, :id => '5109'
If neither of these options work please post your routes entry so we can try something else.
In Firefox, if I try to submit a post without a title, I get: 1 error prohibited this post from being saved.
But when I run my test. It's a different story.
My Post model has validates_presence_of :title. My test looks like:
require 'spec_helper'
describe 'Users' do
it 'registered users should not be able to post without a title', :js => true do
user = Factory(:user)
visit new_post_path
current_path.should eq(new_post_path)
fill_in 'post[markdown_description]', :with => 'Bar'
click_on 'Submit your post'
page.should have_content('error')
end
end
By the way, I am using Selenium (:js => true), because my submit button is actually an anchor link with some JS. Basically, when the link is clicked, JS triggers the form to be submitted.
Rspec returns:
Running: spec/requests/users_spec.rb
F
Failures:
1) Users registered users should be able to post
Failure/Error: page.should have_content('error')
expected there to be content "error" in ""
# ./spec/requests/users_spec.rb:13:in `block (2 levels) in <top (required)>'
Finished in 7.9 seconds
1 example, 1 failure
Failed examples:
rspec ./spec/requests/users_spec.rb:4 # Users registered users should be able to post
The request may not make it to the controller action if you have before_filters. Check the log to make sure that the correct parameters are posting and that the action is not redirecting.
Another option is to include this in your spec:
click_on 'Submit your post'
save_and_open_page
which opens the current page in the browser so you can see what is actually being rendered.
So I have a route that looks like this:
scope "4" do
scope "public" do
scope ":apikey" do
resources :shops
end
end
end
And a bunch of controller specs, an example of which looks like this:
describe ShopsController do
describe "when responding to a GET" do
context "#new" do
it "should create a new instance of the shop class" do
get :new
#shop.should_not_be_nil
end
end
end
end
In rake routes, as well as via a web browser, this controller/action works fine. However, RSpec throws:
1) ShopsController when responding to a GET#new should create a new instance of the shop class
Failure/Error: get :new
ActionController::RoutingError:
No route matches {:controller=>"shops", :action=>"new"}
# ./spec/controllers/shops_controller_spec.rb:9:in `block (4 levels) in <top (required)>'
When I remove the scope statements from the route, the tests work fine. Is there a way to "inform" RSpec of the route scopes?
Thanks in advance!
According to your routes, :apikey is a required parameter, so you need to add it to your get:
get :new, :apikey => "something"
Also you should change the expectation in your next line to this:
assigns[:shop].should_not be_nil
Use assigns to check the controller's instance variables, and separate should_not from the matcher with a space, not an underscore. That last bit takes some getting used to.
UPDATE 4
See solution below!
**Update 3 **
If anyone is actually still reading this (I appreciate it!) I've been struggling around my code today (yes still a noob and in chapter 11 of the ruby on rails tutorial).
I've supposedly reset back to my last commit:
$ cd rails_screencast/sample_app/
$ git reset --hard 2396c0d288d132ffc43c82d5cbbc736a5258eed2
HEAD is now at 2396c0d Micropost Validations
When I check the site on local host it actually shows a list of users and not an ERROR page but when I run the test suite (autotest with spork - I've reset those a few times too to be sure) I still get all errors such as these shown below. I'm very curious about the "Could not find table 'users'" as it is in EVERY error #
108) Users signin success should sign a user in and out
Failure/Error: user = Factory(:user)
ActiveRecord::StatementInvalid:
Could not find table 'users'
# ./spec/requests/users_spec.rb:56:in `block (4 levels) in <top (required)>'
Finished in 0.9872 seconds
108 examples, 108 failures
Time to keep on plugging and looking at all these errors, if anyone can offer any insight or hints or ideas what to check I would appreciate it! Or if you need additional information I can post that too (just be very specific to which files to see as I'm not totally fluent in the lingo as many are already)
Update 2:
It seems that my reset messed something up with the factory settings as sometimes all my errors are pointing to line 5 of my micropost_spec.rb file specifically # the #user = Factory(:user) line... almost like my factories file isn't linked to anything any more. I am wondering if a rake db:migrate would solve any of my problems... or just create new problems... I only have sample data filling in with faker
Any ideas?
Is it possible to revert my file system back to a previous commit and start over? ... when I was green
Failures:
1) Micropost should create a new instance with valid attributes
Failure/Error: #user = Factory(:user)
ActiveRecord::StatementInvalid:
Could not find table 'users'
# ./spec/models/micropost_spec.rb:5:in `block (2 levels) in <top (required)>'
2) Micropost user associations should have a user attribute
Failure/Error: #user = Factory(:user)
ActiveRecord::StatementInvalid:
Could not find table 'users'
# ./spec/models/micropost_spec.rb:5:in `block (2 levels) in <top (required)>'
3) Micropost user associations should have the right associated user
Failure/Error: #user = Factory(:user)
ActiveRecord::StatementInvalid:
Could not find table 'users'
# ./spec/models/micropost_spec.rb:5:in `block (2 levels) in <top (required)>'
4) Micropost validations should have a user id
Failure/Error: #user = Factory(:user)
ActiveRecord::StatementInvalid:
Could not find table 'users'
# ./spec/models/micropost_spec.rb:5:in `block (2 levels) in <top (required)>'
5) Micropost validations should require nonblank content
Failure/Error: #user = Factory(:user)
ActiveRecord::StatementInvalid:
Could not find table 'users'
# ./spec/models/micropost_spec.rb:5:in `block (2 levels) in <top (required)>'
6) Micropost validations should reject long content
Failure/Error: #user = Factory(:user)
ActiveRecord::StatementInvalid:
Could not find table 'users'
# ./spec/models/micropost_spec.rb:5:in `block (2 levels) in <top (required)>'
Update 1:
I'm getting errors from 4 to 6 to 111 all with a recurring theme of
1) Micropost should create a new instance with valid attributes
Failure/Error: #user = Factory(:user)
ActiveRecord::StatementInvalid:
Could not find table 'users'
# ./spec/models/micropost_spec.rb:53:in `block (2 levels) in <top (required)>'
Specifically the "Could not find table 'users'" - I copied the code from the tutorial git for the micropost_spec.rb file but didn't seem to fix it- maybe someone can help direct me to what the table is referring to?
////////////////////////////////////// ORIGINAL BELOW ////////////////////////////////
I am working in the Ruby on Rails Tutorial lesson 11 and am trying to populate my db to show the microposts
when I did the rake db:populate command it gave me the following:
macbook:sample_app macbook$ rake db:populate
(in /Users/macbook/rails_screencast/sample_app)
db/test.sqlite3 already exists
db/test.sqlite3 already exists
db/development.sqlite3 already exists
-- create_table("microposts", {:force=>true})
-> 0.0090s
-- add_index("microposts", ["user_id"], {:name=>"index_microposts_on_user_id"})
-> 0.0074s
-- create_table("users", {:force=>true})
-> 0.0243s
-- add_index("users", ["email"], {:name=>"index_users_on_email", :unique=>true})
-> 0.0094s
-- initialize_schema_migrations_table()
-> 0.0167s
-- assume_migrated_upto_version(20110614132314, "db/migrate")
-> 0.0432s
rake aborted!
Validation failed: Email is invalid
I ran it a couple times and kept getting the same error... when I visited the site on a browser it was like none of my sample users were there...
require 'faker'
namespace :db do
desc "Fill database with sample data"
task :populate => :environment do
Rake::Task['db:reset'].invoke
admin = User.create!(:name => "Foo Bar",
:email => "foo#bar.com",
:password => "foobar",
:password_confirmation => "foobar")
admin.toggle!(:admin)
99.times do |n|
name = Faker::Name.name
email = "example-#{n+1}#railstutorial.org"
password = "password"
User.create!(:name => name,
:email => email,
:password => password,
:password_confirmation => password)
end
User.all(:limit => 6).each do |user|
50.times do
user.microposts.create!(:content => Faker::Lorem.sentence(5))
end
end
end
end
then I decided oh maybe rake db:reset will purge my sample database and I can run the populate again with fresh stuff... bad assumption
my test suite now shows:
Finished in 0.99915 seconds
111 examples, 111 failures
Now before I mess more stuff up I'm looking for some advice where to go next ...
Michael (author of the railstutorial.org) responded to my email request!
If you're missing a table when running the test suite, it's probably an indication that you need to run:
rake db:test:prepare
YUP!! YAYYYY
Finished in 4.82 seconds
108 examples, 0 failures
CAKE TIME!
The db:populate that you're showing does a db:reset itself, so doing it manually can't have caused any problem that wasn't already happening with the db:populate.
You can just delete your db/*.sqlite3 files and start from fresh. There's nothing obvious in that db:populate code which would explain why the email validation failed, you'd have to show the User model and the validations you have in there for us to diagnose that initial issue.