I just added the Rolify gem, and am running some rspec tests.
2 tests are as follows:
describe "roles" do
before(:each) do
@user = FactoryGirl.create(:user)
end
it "should not approve incorrect roles" do
@user.add_role :moderator
@user.has_role? :admin
should be_false
end
it "should approve correct roles" do
@user.add_role :moderator
@user.has_role? :moderator
should be_true
end
end
The test result is:
1) User roles should not approve incorrect roles
Failure/Error: should be_false
expected: false value
got: #<User id: nil, email: "", encrypted_password: "", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, confirmation_token: nil, confirmed_at: nil, confirmation_sent_at: nil, name: nil, position: nil, location: nil, admin: false, archived: false, public_email: false, created_at: nil, updated_at: nil>
# ./spec/models/user_spec.rb:70:in `block (3 levels) in <top (required)>'
Finished in 1.37 seconds
7 examples, 1 failure
Failed examples:
rspec ./spec/models/user_spec.rb:67 # User roles should not approve incorrect roles
Randomized with seed 13074
factories.rb
FactoryGirl.define do
factory :user do
sequence(:name) {|n| "Example User #{n}"}
sequence(:email) {|n| "email#{n}@program.com" }
position "Regular"
location "Anywhere, USA"
public_email false
password "foobar"
password_confirmation "foobar"
confirmed_at Time.now
end
end
How is the first test is failing with a nil object, but the second is passing?
EDIT
Upon further inspection, any test for should be_true
passes, and any test for should be_false
fails, regardless of whether the added role matches the checked role.
When your tests do should be_true
what is happening is the should call is being delegated to the subject object (see RSpec docs for implicit receiver). In this case, your subject object is a User instance that has not yet been saved to the database. If your user_spec.rb file starts with describe User do
, RSpec is automatically providing this default subject of User.new (see RSpec docs for implicit subject).
What this means is that your tests are essentially doing User.new.should be_true
and User.new.should be_false
. Since a User object will always evaluate to true, the should be_true
test will always pass (although probably not for the reason you wanted it to) and the should be_false will always fail.
Based on the way your tests are written, maybe you meant something more like this:
describe "roles" do
before(:each) do
@user = FactoryGirl.create(:user)
end
it "should not approve incorrect roles" do
@user.add_role :moderator
@user.has_role?(:admin).should be_false
end
it "should approve correct roles" do
@user.add_role :moderator
@user.has_role?(:moderator).should be_true
end
end