Reputation: 2227
Having trouble with a rspec spec. The actual code seems to be working fine, but my spec is still failing. I'm using FactoryGirl, Rspec and Capybara. This is part of spec/features/admin/admin_users_spec.rb:
require 'spec_helper'
describe "Admin::Users" do
subject { page }
context "When admin signed in" do
let(:admin) { FactoryGirl.create(:admin) }
let(:user) { FactoryGirl.create(:user) }
before { sign_in admin }
context "when visiting admin users" do
before { visit admin_users_path }
it_should_behave_like "admin visiting admin page"
it { should have_content('- User Index') }
it { should have_content(user.email) } # This test is failing
end
end
end
The test that is failing has the comment.
Here is my factories for users.
require 'faker'
FactoryGirl.define do
factory :user do
email { Faker::Internet.email }
admin false
super_admin false
password "password"
password_confirmation "password"
confirmed_at Time.now
factory (:admin) do
admin true
end
factory (:super_admin) do
admin true
super_admin true
end
end
end
The idea that when you go to the index for users in the admin dashboard, admins should see a list of users. So in addition to the current admin, I create another user to populate the test database. Here is a sample failure message:
Failures:
1) Admin::Users When admin signed in when visiting admin users should text "[email protected]"
Failure/Error: it { should have_content(user.email) }
expected to find text "[email protected]" in "Under The Gun Theater Admin Edit profile Logout Dashboard Users Posts Pages Shows Classes People Photos Admin Dashboard - User Index Email Roles Last Logged In [email protected] admin May 18, 2014 11:59 Logged in as [email protected]"
# ./spec/features/admin/admin_users_spec.rb:53:in `block (4 levels) in <top (required)>'
As you can see, the table that is generated on the page only includes the admin's email address. The other user "[email protected]" is not found. Again, when I actually log into the app it works, so I'm not sure why this test is not working.
Upvotes: 0
Views: 1335
Reputation: 3822
Your user is not being created until after you've loaded the page. let
s are lazy in RSpec. The user record gets created on this line:
it { should have_content(user.email) }
which will always fail since the user wasn't created before the time that the page was loaded. You can change let(:user)
to let!(:user)
, which will run it eagerly before the test. You might want to consider a different structure though, which helps avoid these issues:
admin = create(:user, :admin)
user = create(:user)
sign_in admin
visit admin_users_path
expect(page).to have_content('- User Index')
expect(page).to have_content(user.email)
Upvotes: 2
Reputation: 13014
Use let!
instead of let
for user
.
let
is lazily evaluated, that is, user
won't come into existence till something is called upon it. let!
helps out in sorting this issue by eagerly evaluating the block.
let!(:user) { FactoryGirl.create(:user) }
Read more about let and let! here.
OR, you can create
a user manually in before
block as:
before do
@user = FactoryGirl.create(:user)
sign_in admin
end
#corresponding test:
it { should have_content(@user.email) } # This test should pass
Upvotes: 4