Rails Tests Not Found - Undefined local variable or method "response" - ruby-on-rails-3

I'm trying to follow Michael Hartl's Rails 3 tutorial and I'm running into an error I can't find explained elsewhere. Under Section 9.2.1, I'm getting an error when trying to run a test for non-signed-in users trying to update a profile page.
describe "submitting to the update action" do
before { put user_path(user) }
specify { response.should redirect_to(signin_path) }
end
The error I'm getting is "undefined local variable or method 'response' for # (NameError)". This is a response to "bundle exec rspec spec/". When I comment out the offending line, all tests instantiate and pass. I've tried replacing "response" with things like "response.body" and "page" but neither seem to help.
I'm not sure what the issue is because as I'm moving forward with the tutorial, similar blocks are passing without incident.
Here's the full error text:
C:\Ruby193\bin\ruby.exe -e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift) C:\Ruby193\bin\rake spec
Testing started at 7:39 PM ...
C:/Ruby193/bin/ruby.exe -S rspec ./spec/models/user_spec.rb ./spec/requests/authentication_pages_spec.rb ./spec/requests/static_pages_spec.rb ./spec/requests/user_pages_spec.rb
Rack::File headers parameter replaces cache_control after Rack 1.5.
C:/Users/Jeff/Documents/rails_projects/sample_app/spec/requests/authentication_pages_spec.rb:60:in `block (5 levels) in <top (required)>': undefined local variable or method `response' for #<Class:0x4894908> (NameError)
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:244:in `module_eval'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:244:in `subclass'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:230:in `describe'
from C:/Users/Jeff/Documents/rails_projects/sample_app/spec/requests/authentication_pages_spec.rb:58:in `block (4 levels) in <top (required)>'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:244:in `module_eval'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:244:in `subclass'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:230:in `describe'
from C:/Users/Jeff/Documents/rails_projects/sample_app/spec/requests/authentication_pages_spec.rb:51:in `block (3 levels) in <top (required)>'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:244:in `module_eval'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:244:in `subclass'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:230:in `describe'
from C:/Users/Jeff/Documents/rails_projects/sample_app/spec/requests/authentication_pages_spec.rb:48:in `block (2 levels) in <top (required)>'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:244:in `module_eval'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:244:in `subclass'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:230:in `describe'
from C:/Users/Jeff/Documents/rails_projects/sample_app/spec/requests/authentication_pages_spec.rb:46:in `block in <top (required)>'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:244:in `module_eval'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:244:in `subclass'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:230:in `describe'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/rspec-core-2.12.2/lib/rspec/core/dsl.rb:18:in `describe'
from C:/Users/Jeff/Documents/rails_projects/sample_app/spec/requests/authentication_pages_spec.rb:3:in `<top (required)>'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/activesupport-3.2.11/lib/active_support/dependencies.rb:245:in `load'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/activesupport-3.2.11/lib/active_support/dependencies.rb:245:in `block in load'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/activesupport-3.2.11/lib/active_support/dependencies.rb:236:in `load_dependency'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/activesupport-3.2.11/lib/active_support/dependencies.rb:245:in `load'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/rspec-core-2.12.2/lib/rspec/core/configuration.rb:789:in `block in load_spec_files'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/rspec-core-2.12.2/lib/rspec/core/configuration.rb:789:in `each'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/rspec-core-2.12.2/lib/rspec/core/configuration.rb:789:in `load_spec_files'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/rspec-core-2.12.2/lib/rspec/core/command_line.rb:22:in `run'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/rspec-core-2.12.2/lib/rspec/core/runner.rb:80:in `run'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/rspec-core-2.12.2/lib/rspec/core/runner.rb:17:in `block in autorun'
rake aborted!
C:/Ruby193/bin/ruby.exe -S rspec ./spec/models/user_spec.rb ./spec/requests/authentication_pages_spec.rb ./spec/requests/static_pages_spec.rb ./spec/requests/user_pages_spec.rb failed
-e:1:in `load'
-e:1:in `<main>'
Tasks: TOP => spec
(See full trace by running task with --trace)
Process finished with exit code 1
Empty test suite.
I'm pretty sure it's not a typo somewhere but here's the offending file (authentication_pages_spec.rb). (have_title() is a method I found here for fixing an error because apparently have_selector('title',...) is no longer valid syntax.)
require 'spec_helper'
describe "Authentication" do
subject { page }
describe "signin page" do
before { visit signin_path }
it {should have_selector('h1', text: 'Sign in') }
it {should have_title('Sign in') }
end
describe "signin" do
before { visit signin_path }
describe "with invalid information" do
before { click_button "Sign in" }
it { should have_title('Sign in') }
it { should have_selector('div.alert.alert-error', text: 'Invalid') }
describe "after visiting another page" do
before { click_link "Home" }
it { should_not have_selector('div.alert.alert-error') }
end
end
describe "with valid information" do
let(:user) { FactoryGirl.create(:user) }
before { sign_in user }
it { should have_title(user.name) }
it { should have_link('Profile', href: user_path(user)) }
it { should have_link('Settings', href: edit_user_path(user)) }
it { should have_link('Sign out', href: signout_path) }
it { should_not have_link('Sign in', href: signin_path) }
describe "followed by signout" do
before { click_link "Sign out" }
it { should have_link('Sign in') }
end
end
end
describe "authorization" do
describe "for non-signed-in users" do
let(:user) { FactoryGirl.create(:user) }
describe "in the Users controller" do
describe "visiting the edit page" do
before { visit edit_user_path(user) }
it { should have_title('Sign in') }
end
describe "submitting to the update action" do
before { put user_path(user) }
specify ( response.should redirect_to(signin_path) )
end
describe "as wrong user" do
let(:user) { FactoryGirl.create(:user) }
let(:wrong_user) { FactoryGirl.create(:user, email: "wrong#example.com") }
before { sign_in user }
describe "visiting Users#edit_page" do
before { visit edit_user_path(wrong_user) }
it { should_not have_title(full_title("Edit user")) }
end
describe "submitting a PUT request to the Users#update action" do
before { put user_path(wrong_user) }
specify { response.should redirect_to(root_path) }
end
end
end
end
end
end

What version of Capybara are you running?
$ bundle exec gem list | grep capybara
If you're running version >= 2.0 you should look again at your Gemfile and specifically mark the version to be the same as the tutorial (1.1.2).
Gemfile
group :test do
gem 'capybara', '1.1.2'
end
If you desperately want to use the latest version, you'll have to make some changes, outlined in the following StackOverflow Q&As:
Capybara methods are undefined
capybara: post, get methods not working when changing name of requests directory to features
RSpec & Capybara 2.0 tripping up my have_selector tests
Update
Okay, you're going to kick yourself, but after cloning your repo and getting the same error, your problem is obvious (syntax highlighting is your friend):
On Line 77 of your spec/requests/authentication_pages_spec.rb you have:
specify ( response.should redirect_to(signin_path) )
It should be:
specify { response.should redirect_to(signin_path) }
After fixing that, your tests will pass.

Related

What does mean <top (required)> in rspec?

I have some rspec test. For example
require 'spec_helper'
describe UsersController do
before (:each) do
#user = FactoryGirl.create(:user)
sign_in #user
end
describe "GET 'show'" do
it "should be successful" do
get :show, :id => #user.id
response.should be_success
end
it "should find the right user" do
get :show, :id => #user.id
assigns(:user).should == #user
end
end
end
When I run the rspec i get some errors
Failures:
1) UsersController GET 'show' should be successful
Failure/Error: #user = FactoryGirl.create(:user)
ActiveRecord::StatementInvalid:
SQLite3::SQLException: near "SAVEPOINT": syntax error: SAVEPOINT active_record_1
# ./spec/controllers/users_controller_spec.rb:6:in `block (2 levels) in <top (required)>'
2) UsersController GET 'show' should find the right user
Failure/Error: #user = FactoryGirl.create(:user)
ActiveRecord::StatementInvalid:
SQLite3::SQLException: near "SAVEPOINT": syntax error: SAVEPOINT active_record_1
# ./spec/controllers/users_controller_spec.rb:6:in `block (2 levels) in <top (required)>'
rspec ./spec/controllers/users_controller_spec.rb:12 # UsersController GET 'show' should be successful
rspec ./spec/controllers/users_controller_spec.rb:17 # UsersController GET 'show' should find the right user
What does the mean and what could be the problem with that rspec?
Host is CentOS5 and the included SQLite version is old and dont work with the sqlite3 gem.
So i had to config the bundler to use a newer installed sqlite version.
bundle config build.sqlite3 \
--with-sqlite3-include=/package/host/localhost/sqlite-3/include \
--with-sqlite3-lib=/package/host/localhost/sqlite-3/lib
Followed by a bundle install
Problem solved.

Chapter 9 test failed Ruby on rails tutorial

Im newbie in Rails and I am reading the Michael Hartl's RubyOnRails tutorial... I have read about Chapter 9 similar problems but I didnt resolve my own problem, so here is my github repository and the failed test... Perhaps someone can help me, thanks so much ;)
https://github.com/AntonioCortinaL/sample_app
1) UserPages edit page
Failure/Error: it { should have_selector('h1', text: "Update your profile") }
expected css "h1" with text "Update your profile" to return something
# ./spec/requests/user_pages_spec.rb:61:in `block (4 levels) in <top (required)>'
2) UserPages edit page
Failure/Error: it { should have_selector('title', text: "Edit user") }
expected css "title" with text "Edit user" to return something
# ./spec/requests/user_pages_spec.rb:62:in `block (4 levels) in <top (required)>'
3) UserPages edit page
Failure/Error: it { should have_link('change', href: 'http://gravatar.com/emails') }
expected link "change" to return something
# ./spec/requests/user_pages_spec.rb:63:in `block (4 levels) in <top (required)>'
4) UserPages edit with invalid information
Failure/Error: before { click_button "Save changes" }
Capybara::ElementNotFound:
no button with value or id or text 'Save changes' found
# (eval):2:in `click_button'
# ./spec/requests/user_pages_spec.rb:67:in `block (4 levels) in <top (required)>'
5) UserPages edit with valid information
Failure/Error: fill_in "Name", with: new_name
Capybara::ElementNotFound:
cannot fill in, no text field, text area or password field with id, name, or label 'Name' found
# (eval):2:in `fill_in'
# ./spec/requests/user_pages_spec.rb:76:in `block (4 levels) in <top (required)>'
6) UserPages edit with valid information
Failure/Error: fill_in "Name", with: new_name
Capybara::ElementNotFound:
cannot fill in, no text field, text area or password field with id, name, or label 'Name' found
# (eval):2:in `fill_in'
# ./spec/requests/user_pages_spec.rb:76:in `block (4 levels) in <top (required)>'
7) UserPages edit with valid information
Failure/Error: fill_in "Name", with: new_name
Capybara::ElementNotFound:
cannot fill in, no text field, text area or password field with id, name, or label 'Name' found
# (eval):2:in `fill_in'
# ./spec/requests/user_pages_spec.rb:76:in `block (4 levels) in <top (required)>'
8) UserPages edit with valid information
Failure/Error: fill_in "Name", with: new_name
Capybara::ElementNotFound:
cannot fill in, no text field, text area or password field with id, name, or label 'Name' found
# (eval):2:in `fill_in'
# ./spec/requests/user_pages_spec.rb:76:in `block (4 levels) in <top (required)>'
9) UserPages edit with valid information
Failure/Error: fill_in "Name", with: new_name
Capybara::ElementNotFound:
cannot fill in, no text field, text area or password field with id, name, or label 'Name' found
# (eval):2:in `fill_in'
# ./spec/requests/user_pages_spec.rb:76:in `block (4 levels) in <top (required)>'
Edit after Paul Fioravanti answer:
Ok, thanks... I changed it for this:
before do
sign_in user
visit edit_user_path(user)
end
Now its 5 errors
1) UserPages edit with valid information
Failure/Error: fill_in "Confirm Password", with: user.password
Capybara::ElementNotFound:
cannot fill in, no text field, text area or password field with id, name, or label 'Confirm Password' found
# (eval):2:in `fill_in'
# ./spec/requests/user_pages_spec.rb:81:in `block (4 levels) in <top (required)>'
2) UserPages edit with valid information
Failure/Error: fill_in "Confirm Password", with: user.password
Capybara::ElementNotFound:
cannot fill in, no text field, text area or password field with id, name, or label 'Confirm Password' found
# (eval):2:in `fill_in'
# ./spec/requests/user_pages_spec.rb:81:in `block (4 levels) in <top (required)>'
3) UserPages edit with valid information
Failure/Error: fill_in "Confirm Password", with: user.password
Capybara::ElementNotFound:
cannot fill in, no text field, text area or password field with id, name, or label 'Confirm Password' found
# (eval):2:in `fill_in'
# ./spec/requests/user_pages_spec.rb:81:in `block (4 levels) in <top (required)>'
4) UserPages edit with valid information
Failure/Error: fill_in "Confirm Password", with: user.password
Capybara::ElementNotFound:
cannot fill in, no text field, text area or password field with id, name, or label 'Confirm Password' found
# (eval):2:in `fill_in'
# ./spec/requests/user_pages_spec.rb:81:in `block (4 levels) in <top (required)>'
5) UserPages edit with valid information
Failure/Error: fill_in "Confirm Password", with: user.password
Capybara::ElementNotFound:
cannot fill in, no text field, text area or password field with id, name, or label 'Confirm Password' found
# (eval):2:in `fill_in'
# ./spec/requests/user_pages_spec.rb:81:in `block (4 levels) in <top (required)>'
Your user_pages_spec.rb test says:
describe "edit" do
let(:user) { FactoryGirl.create(:user) }
before { visit edit_user_path(user) }
# ...
end
You forgot to sign_in before visiting the edit_user_path.
Here's the tutorial's equivalent spec.
Edit:
As for your second issue see the equivalent link in the Rails Tutorial here. Compare your user_pages_spec.rb here and here: you can see you're trying to fill_in a "Confirm Password" field and a "Confirmation" field, only one of which actually exists in your app...
Ensure that you give each user a valid remember token using the rails console before running the test suite. Follow 8.2.4 for precise instructions.

RSpec let method gives nil when used in specs

When I run this test
require 'spec_helper'
describe AssignmentsController do
let(:user) { create(:user) }
let(:course) { create(:course) }
describe "GET 'index'" do
it "returns http success" do
assignment = user.assignments.build(name: "Hello 2", start_date: "5/20/2000", due_date: "5/21/2000")
get :index
assigns(:assignment).should eq([assignment])
end
end
end
I get this
Failure:
1) AssignmentsController GET 'index' returns http success
Failure/Error: get :index
NoMethodError:
undefined method `assignments' for nil:NilClass
# ./app/controllers/assignments_controller.rb:5:in `index'
# ./spec/controllers/assignments_controller_spec.rb:29:in `block (3 levels) in <top (required)>'
Why this be since I defined the user variable with lets above
If you look carefully, you'll see that the error originating from your controller on line 5, not the spec file. Everything should be fine with the let statement the way you have it.

Unexpected rspec behavior Ruby on Rails Turorial chapter 12

I am seeing an error that is only dependent on the location of the line:
should change(Relationship, :count).by(-1)
For example, with the code:
it "should destroy a relationship using Ajax" do
lambda do
xhr :delete, :destroy, :id => #relationship
response.should be_success
end.should change(Relationship, :count).by(-1) #<<-line is here
I get the rspec error:
1) RelationshipsController DELETE 'destroy' should destroy a relationship using Ajax
Failure/Error: xhr :delete, :destroy, :id => #relationship
ActionView::MissingTemplate:
Missing template relationships/destroy with {:handlers=>[:erb, :rjs, :builder, :rhtml, :rxml], :formats=>[:js, :html], :locale=>[:en, :en]} in view paths "#<RSpec::Rails::ViewRendering::PathSetDelegatorResolver:0x00000100a5b5f8>"
# ./app/controllers/relationships_controller.rb:16:in `destroy'
# ./spec/controllers/relationships_controller_spec.rb:44:in `block (4 levels) in <top (required)>'
# ./spec/controllers/relationships_controller_spec.rb:43:in `block (3 levels) in <top (required)>'
But with the code:
it "should destroy a relationship using Ajax" do
lambda do
xhr :delete, :destroy, :id => #relationship
response.should be_success
should change(Relationship, :count).by(-1) #<<-Line moved to here
end
... the test passes.
I am seeing expected behavior when I use a web browser. Unfollowing a user adjusts totals correctly.
So, are these two rspec tests not equivalent? Am I falsely reassured that the second test passes? If they are functionally equivalent, why does the first one fail?
Seems this was due, in part, to having confused
./app/controllers/relationships_controller.rb
with
./spec/controllers/relationships_controller_spec.rb
Code pasted into the wrong file (appropriately) generated no syntax errors. Fixing my error lead to passing rspec tests.

test rails controllers that are not in spec/controllers with rspec 2

rspec expects your controller specs to be in /spec/controllers. I have some modules that are included in my controllers. The only way to test them, near as I can tell, is to create a dummy controller, include the module in it, and test from there. The problem is that the module specs are in /spec/lib/module, and so ControllerExampleGroup is not included, which means I can't call the helper methods get "action" etc.
I can manually import these, which gets me most of the way there, but I then get this error:
Failure/Error: Unable to find matching
line from backtrace undefined method
`path_set' for nil:NilClass
activesupport-3.0.3/lib/active_support/whiny_nil.rb:48:in
`method_missing'
rspec-rails-2.2.1/lib/rspec/rails/view_rendering.rb:68
rspec-core-2.2.1/lib/rspec/core/example_group.rb:291:in
`instance_eval'
rspec-core-2.2.1/lib/rspec/core/example_group.rb:291:in
`instance_eval_with_rescue'
rspec-core-2.2.1/lib/rspec/core/hooks.rb:39:in
`run_in'
rspec-core-2.2.1/lib/rspec/core/hooks.rb:70:in
`run_all'
rspec-core-2.2.1/lib/rspec/core/hooks.rb:70:in
`each'
rspec-core-2.2.1/lib/rspec/core/hooks.rb:70:in
`run_all'
rspec-core-2.2.1/lib/rspec/core/hooks.rb:106:in
`run_hook'
rspec-core-2.2.1/lib/rspec/core/example_group.rb:194:in
`eval_after_eachs'
rspec-core-2.2.1/lib/rspec/core/example_group.rb:194:in
`each'
rspec-core-2.2.1/lib/rspec/core/example_group.rb:194:in
`eval_after_eachs'
rspec-core-2.2.1/lib/rspec/core/example.rb:130:in `run_after_each'
rspec-core-2.2.1/lib/rspec/core/example.rb:44:in `run'
rspec-core-2.2.1/lib/rspec/core/example.rb:88:in `with_around_hooks'
rspec-core-2.2.1/lib/rspec/core/example.rb:37:in `run'
rspec-core-2.2.1/lib/rspec/core/example.rb:81:in `with_pending_capture'
rspec-core-2.2.1/lib/rspec/core/example.rb:80:in `catch'
rspec-core-2.2.1/lib/rspec/core/example.rb:80:in `with_pending_capture'
rspec-core-2.2.1/lib/rspec/core/example.rb:36:in `run'
rspec-core-2.2.1/lib/rspec/core/example_group.rb:261:in
`run_examples'
rspec-core-2.2.1/lib/rspec/core/example_group.rb:257:in
`map'
rspec-core-2.2.1/lib/rspec/core/example_group.rb:257:in
`run_examples'
rspec-core-2.2.1/lib/rspec/core/example_group.rb:231:in
`run'
rspec-core-2.2.1/lib/rspec/core/example_group.rb:232:in
`run'
rspec-core-2.2.1/lib/rspec/core/example_group.rb:232:in
`map'
rspec-core-2.2.1/lib/rspec/core/example_group.rb:232:in
`run'
rspec-core-2.2.1/lib/rspec/core/command_line.rb:27:in
`run'
rspec-core-2.2.1/lib/rspec/core/command_line.rb:27:in
`map'
rspec-core-2.2.1/lib/rspec/core/command_line.rb:27:in
`run'
rspec-core-2.2.1/lib/rspec/core/reporter.rb:12:in `report'
rspec-core-2.2.1/lib/rspec/core/command_line.rb:24:in
`run'
rspec-core-2.2.1/lib/rspec/core/runner.rb:55:in
`run_in_process'
rspec-core-2.2.1/lib/rspec/core/runner.rb:46:in
`run'
rspec-core-2.2.1/lib/rspec/core/runner.rb:10:in
`autorun'
/Users/jeffdeville/.rvm/gems/ree-1.8.7-2010.02/bin/rspec:19
Suggestions?
If you have a spec that's not in one of the standard locations, you can always tell rspec by passing a :type attribute to the describe method:
describe MyController, :type => :controller do
...
end
For specing modules that are meant to be included by a controller, rspec 2 has a very handy way to create anonymous controllers.
describe MyModule do
context "when included by a controller", :type => :controller do
controller do # anonymous subclass of ActionController::Base
include MyModule
def index
head :ok
end
end
it "works" do
get "index"
response.should be_success
end
end
end
More info here in the rspec docs (generated from Cucumber features): http://relishapp.com/rspec/rspec-rails/dir/controller-specs/anonymous-controller