I am using some of these tools for the first time. I have read through the docs but wanted to ask here exactly what I’m trying to achieve.
I have a set of users that I want to test some actions I can do in a controller spec. When each user is created, there are a set of callbacks that take place to create associated objects.
I’d like to have access to these user instances and the associated objects of that ActiveRecord class. So for example, a user will have a set of lists so I’d like to be able to call user1.lists for example.
Also, I’d like to isolate this setup at the top and use either let’s or a before black. It seems that just calling let like this:
# will test that get_count_for_list will return 5
describe ApiController do
# why same name - seems really confusing!
let(:user) { FactoryGirl.create(:user) }
let(:user2) { FactoryGirl.create(:user2) }
doesn’t call the associated callbacks. Is this correct? Or is it possibly a timing issue?
I like the syntax of using let and being able to access these objects in my ExampleGroups such as user.id but can’t access user.lists. Currently I am doing something like:
# will test that get_count_for_list will return 5
describe ApiController do
# why same name - seems really confusing!
let(:user) { FactoryGirl.create(:user) }
let(:user2) { FactoryGirl.create(:user2) }
let(:user3) { FactoryGirl.create(:user3) }
before do
FactoryGirl.create(:user2)
FactoryGirl.create(:user3)
end
but feel that there has to be a better way. Am I creating these user’s twice?
thx
edit 1
I’ve isolated the code in question here. The global_id value is created via a callback. It exists correctly in the db and can be accessed via the corresponding find_by_email’s but using the user2 var’s doesn’t provide access.
require 'spec_helper'
# will test that get_count_for_list will return 5
describe ApiController do
# why same name - seems really confusing!
let!(:user) { FactoryGirl.create(:user) }
let!(:user2) { FactoryGirl.create(:user2) }
let!(:user3) { FactoryGirl.create(:user3) }
before do
session[:user_id]=user.id # works
end
describe 'FOLLOW / UNFOLLOW options' do
it 'shall test the ability to follow another user' do
puts "user1: " + user.global_id.to_s # doesn't output anything
u2=User.find_by_email('jo@jo.com') # corresponds to user2
post :follow, :global_id => user2.global_id # doesn't work
#post :follow, :global_id => u2.global_id #works
u3=User.find_by_email('su@su.com')
puts "user_3" + u3.global_id.to_s # outputs correct value
post :follow, :global_id => user3.global_id #doesn't work
#post :follow, :global_id => u3.global_id # works
post :unfollow, :global_id => user.following.sample(1)
response.code.should eq('200')
end
end
end
Check the rspec doc: https://www.relishapp.com/rspec/rspec-core/v/2-11/docs/helper-methods/let-and-let
Note that let is lazy-evaluated: it is not evaluated until the first time the method it defines is invoked. You can use let! to force the method’s invocation before each example.
In other words if you use
letalong withfactory_girla record will not be created before let-variable invocation.The correct code is: