29
votes

I have the following code inside most of my tests:

describe 'index'
 let(:company) { FactoryGirl.create(:company) }
 let(:user) { FactoryGirl.create(:user, company: company) }

 before do
   sign_in user
   visit products_path
 end
...
end

But I'm getting the following warning:

WARNING: let declaration 'user' accessed in a 'before(:all)'

My question is, what is the correct way of doing this? I can't find much information about the warning itself.

Thanks!

EDIT: My goal is to use the user variable so I can pass it on to sign_in, which signs the user in, and use it later on another tests (I check for the company attribute of the User)

3
Seems like this is the right way. Are you sure there isn't a before(:all) that we aren't seeing? - zetetic
Yeah, I assumed there was a before(:all) that you were not showing. Is that not the case? - Peter Alfvin
'Index' is,im guessing, not your top level describe block, is this nested in another describe or context block above it? In other words, are you sure you are not inheriting something. Also, before do is the same as before :each do. Its implied. Can you show the whole spec file? - fontno
'Index' is the first nested describe block. It's inside another describe block, which is the first describe on the file. I'll upload the whole spec file tonight as I'm not on my computer right now - Fabian Silva

3 Answers

29
votes

I had the same problem, I have solved it by declaring all my variables as attributes inside the before block:

describe 'index'

 before(:all) do
   @company = FactoryGirl.create(:company)
   @user = FactoryGirl.create(:user, company: @company)

   sign_in @user
   visit products_path
 end
...
end

Now you can use @user and @company inside your tests, and you shouldn't have any warnings.

3
votes

I'm not sure what you mean by "this" in "what is the correct way of doing this"? Accessing let and subject within a before(:all) is deprecated and will be removed in RSpec 3 with the following explanation from https://github.com/rspec/rspec-core/pull/857:

let and subject declarations are not intended to be called in a before(:all) hook, as they exist to define state that is reset between each example, while before(:all) exists to define state that is shared across examples in an example group.

2
votes

Taking into account Peter's answer I think the correct way is to access the user in a before each block:

before(:each) do
  sign_in user
end