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.
Related
I have configured Rspec Ruby 2.0.0-p0 and Rails 3.2.14 configuration is perfect I'm sure on that but when I try to run rake spec:controllers it gaves me below error on every request action written in spec example -
*** NoMethodError Exception: undefined method `to_sym' for nil:NilClass
I have written specs for controllers before but never come across such situation, help me If any one has fixed same issue....
Here is my spec and error stack
describe UsersController do
before (:each) do
#user = FactoryGirl.create(:user)
sign_in #user
end
describe "GET 'index'" do
it "should be successful" do
get 'index'
response.should be_success
end
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
Here is result -
Failures:
1) UsersController GET 'index' should be successful
Failure/Error: get 'index'
NoMethodError:
undefined method `to_sym' for nil:NilClass
# ./spec/controllers/users_controller_spec.rb:13:in `block (3 levels) in <top (required)>'
2) UsersController GET 'show' should be successful
Failure/Error: get :show, :id => #user.id
NoMethodError:
undefined method `to_sym' for nil:NilClass
# ./spec/controllers/users_controller_spec.rb:21:in `block (3 levels) in <top (required)>'
3) UsersController GET 'show' should find the right user
Failure/Error: get :show, :id => #user.id
NoMethodError:
undefined method `to_sym' for nil:NilClass
# ./spec/controllers/users_controller_spec.rb:26:in `block (3 levels) in <top (required)>'
Finished in 0.4741 seconds
3 examples, 3 failures
Failed examples:
rspec ./spec/controllers/users_controller_spec.rb:12 # UsersController GET 'index' should be successful
rspec ./spec/controllers/users_controller_spec.rb:20 # UsersController GET 'show' should be successful
rspec ./spec/controllers/users_controller_spec.rb:25 # UsersController GET 'show' should find the right user
Randomized with seed 19701
My factory is -
FactoryGirl.define do
factory :user do
first_name 'Test User'
last_name 'Last name'
email 'example#example.com'
password 'changeme'
password_confirmation 'changeme'
company 'RR'
confirmed_at Time.now
end
end
We need company name mandatory to create register user.
class UsersController < ApplicationController
before_filter :authenticate_user!
#authorize_resource
def index
#users = User.all
end
def show
#user = User.find(params[:id])
end
end
here I have added two methods for test in user controller.
Same thing I tried with demo example that works great but not in my project....
Thanks
If you are using devise gem for authentication then you need to specify the devise mapping in controller test cases.
Replace the code in the before(:each) block with below code
#user = FactoryGirl.create(:user)
#request.env['devise.mapping'] = Devise.mappings[:user]
sign_in #user
Finally I fixed issue, it comes due to authenticate_user! method in application controller which inherits to every controllers -
prepend_before_filter :authenticate_user!, :except => [:not_authenticated]
I have added below module to fix issue occurs due to this devise method -(support/controllers_helpers.rb)
module ControllerHelpers
def sign_in(user = double('user'))
if user.nil?
request.env['warden'].stub(:authenticate!).
and_throw(:warden, {:scope => :user})
controller.stub :current_user => nil
else
request.env['warden'].stub :authenticate! => user
controller.stub :current_user => user
end
end
end
finally include above module in spec_helper.rb file
config.include ControllerHelpers, :type => :controller
Got running all controllers specs.
Cheers!!!
more info
I just started some tests on my Rails application in which I use Devise for authentication. I just generated rspec and only added
RSpec.configure do |config|
config.include Devise::TestHelpers, :type => :controller
end
to my spec/support/devise.rb file.
I also added Capybara to the test group in my gemfile, run the bundle command, etc. But as I do visit in my tests, I get a no method error. Here an example of my user_spec.rb:
require 'spec_helper'
describe "Club" do
before(:each) do
#club ||= FactoryGirl.create(:club)
FactoryGirl.create(:membership)
User.all.each{|x| x.delete}
end
describe "privacy" do
it "shouldn't be shown any tournament if the user is private" do
attributes = FactoryGirl.attributes_for(:user)
user = User.create!({private: true}.merge(attributes))
assert(user.private)
visit "/user/#{user.id}/tournaments"
page.should have_no_selector(".tournament-list")
end
end
end
As I run rspec there comes an error like this:
Failures:
1) Club privacy shouldn't be shown any tournament if the user is private
Failure/Error: visit "/user/#{user.id}/tournaments"
NoMethodError:
undefined method `visit' for #<RSpec::Core::ExampleGroup::Nested_3::Nested_1:0x007ff0ea113108>
# ./spec/user_spec.rb:14:in `block (3 levels) in <top (required)>'
For capybara specs I use:
describe "Club", :type => :feature, :js => true do
include Capybara::DSL
it "..."
end
And instead User.all.each{|x| x.delete}, use DatabaseCleaner
You can easily add the Capybara::DSL to RSpec config spec_helper.rb
RSpec.configure do |config|
.....
.......
config.include(Capybara::DSL)
end
How to pass id. my controller is:
class AttachementsController < ApplicationController
def index
#pdf = Attachement.find(params[:resume_id])
# send_file(#pdf.file.url, :type => 'application/pdf', :disposition => 'inline',:stream => false)
redirect_to #pdf.file.url
end
end
and my test case of the controller is:
require 'spec_helper'
describe AttachementsController do
describe "GET 'index'" do
it "should be successful" do
get 'index', :id => "#attachements.id"
response.should be_success
end
end
end
and my error is:
AttachementsController GET 'index' should be successful
Failure/Error: get 'index', :id => "#attachements.id"
ActiveRecord::RecordNotFound:
Couldn't find Attachement without an ID
# ./app/controllers/attachements_controller.rb:3:in `index'
# ./spec/controllers/attachements_controller_spec.rb:7:in `block (3 levels) in <top (required)>'
You don't need the quotes around #attachements.id.
get 'index', :id => #attachements.id
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.
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.