Rails: RSpec - undefined method `cookie_jar' for nil:NilClass
authentication, capybara, rspec, ruby, ruby-on-rails
Solution
RSpec is very particular about the directory that you place your tests. If you put the test in the wrong directory, it won't automagically mix-in the various test helpers that setup different types of tests. It seems your setup is using `spec/features` which is not an approved default directory (`spec/requests`, `spec/integration`, or `spec/api`).
Based on the tutorial page, I'm not sure how they have the `spec_helper.rb` file setup. Though the examples so they are using `spec/requests` to hold the tests.
You can force RSpec to recognize another directory for request specs by using on of the following:
Manually add the proper module to the test file:
# spec/features/pages/index_spec.rb
require 'spec_helper'
describe "Visiting the index page" do
include RSpec::Rails::RequestExampleGroup
# Rest of your test code
context "when the a user has logged in and attempts to visit the page" do
let(:user) { FactoryGirl.create :user }
before do
log_in user
end
specify { response.should redirect_to loggedin_path }
end
end
Include this in your `spec/spec_helper.rb` file:
RSpec::configure do |c|
c.include RSpec::Rails::RequestExampleGroup, type: :request, example_group: {
file_path: c.escaped_path(%w[spec (features)])
}
end
Since this is a tutorial I'd recommend following the standard of including `require 'spec_helper'` at the top of the spec file and that your actual `spec/spec_helper.rb` file has `require 'rspec/rails'`
A minor note, you don't need to put a `specify` inside of an `it` block. They are aliases of each other, so just use one.
context "when the a user has logged in and attempts to visit the page" do
let(:user) { FactoryGirl.create :user }
before do
log_in user
end
# All of the following are the same
it "redirects the user to next page" do
response.should redirect_to loggedin_path
end
it { response.should redirect_to loggedin_path }
specify "redirects the user to next page" do
response.should redirect_to loggedin_path
end
specify { response.should redirect_to loggedin_path }
end
Note, according to the documentation for capybara, you should be able to put your capybara tests into `spec/features`. To make this work, ensure you are loading `require 'capybara/rspec'` in your `spec_helper` or test spec file directly.
However, looking at the source, I didn't see where they are automatically including that directory. You can also try adding the tag `type: :feature` to the outer `describe` block in your test file. Though the more likely solution is to use `spec/requests`.
Problem
Rails newbie. Trying to follow Michael Hartl's tutorial. Stuck trying to add a helper method to simulate log in an RSpec test: ``` describe "when the a user has logged in and attempts to visit the page" do let(:user) { FactoryGirl.create :user } before do log_in user end it "should redirect the user to next page" do specify { response.should redirect_to loggedin_path } end end ``` In my spec/support/utilities.rb: ``` def log_in user visit root_path fill_in "Email", with: user.email fill_in "Password", with: user.password click_button "Log in" cookies[:remember_token] = user.remember_token end ``` Error: ``` Failure/Error: log_in user NoMethodError: undefined method `cookie_jar' for nil:NilClass ``` What gives? Edit, full stack trace: ``` Index page when the a user has logged in and attempts to visit the page should redirect the user to next page Failure/Error: log_in user NoMethodError: undefined method `cookie_jar' for nil:NilClass # ./spec/support/utilities.rb:8:in `log_in' # ./spec/features/pages/index_spec.rb:20:in `block (3 levels) in <top (required)>' ```