I am working on some Cucumber stories for a 'sign up' application which has a number of steps.
Rather then writing a Huuuuuuuge story to cover all the steps at once, which would be bad, I'd rather work through each action in the controller like a regular user. My problem here is that I am storing the account ID which is created in the first step as a session variable, so when step 2, step 3 etc are visited the existing registration data is loaded.
I'm aware of being able to access controller.session[..]
within RSpec specifications however when I try to do this in Cucumber stories it fails with the following error (and, I've also read somewhere this is an anti-pattern etc...):
Using controller.session[:whatever] or session[:whatever]
You have a nil object when you didn't expect it!
The error occurred while evaluating nil.session (NoMethodError)
Using session(:whatever)
wrong number of arguments (1 for 0) (ArgumentError)
So, it seems accession the session store isn't really possible. What I'm wondering is if it might be possible to (and I guess which would be best..):
- Mock out the session store etc
- Have a method within the controller and stub that out (e.g.
get_registration
which assigns an instance variable...)
I've looked through the RSpec book (well, skimmed) and had a look through WebRat etc, but I haven't really found an answer to my problem...
To clarify a bit more, the signup process is more like a state machine - e.g. the user progresses through four steps before the registration is complete - hence 'logging in' isn't really an option (it breaks the model of how the site works)...
In my spec for the controller I was able to stub out the call to the method which loads the model based on the session var - but I'm not sure if the 'antipattern' line also applies to stubs as well as mocks?
Thanks!
@Ajedi32 I ran into the same issue (undefined method 'current_session' for Capybara::RackTest::Driver) and putting this in my step definition fixed the problem for me:
In my controller action, I referred to cookies[:stub_user_id], instead of cookie_jar[:stub_user_id]
Why don't you use FactoryGirl or (Fixjour or Fabricator) with Devise (or Authlogic) and SentientUser? Then you can simply sniff which user is already logged in!
I use a testing-only sign-in solution like Prikka's, but I do it all in Rack instead of creating a new Controller and routes.
Another slight variation:
Re: Ryan's solution:
Does not work with Capybara, unless small adaptation done:
(found here: https://gist.github.com/484787)
My understanding is that you get:
when session[] is accessed before request has been instantiated. In your case, I'd imagine if you put webrats'
visit some_existing_path
before accessing session[] in your step defenition, the error will go away.Now, unfortunately, session doesn't seem to persist across steps (at least, I couldn't find the way), so this bit of information doesn't help to answer your question :)
So, I suppose, Ryan's
session[:user_id] = cookies[:stub_user_id]...
is the way to go. Although, imo, test related code in the application itself doesn't sound right.