I have two models:
# app/models/user.rb
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :confirmable
has_many :teams, dependent: :destroy
end
and
# app/models/team.rb
class Team < ActiveRecord::Base
belongs_to :user
validates_presence_of :user
end
I am trying to test my TeamsController
using Rspec and factory_girl_rails.
Before I can create a new Team I need an authenticated User.
I created a :user factory:
FactoryGirl.define do
factory :user do
first_name "John"
last_name "Doe"
email {|n| "email#{n}@email.com" }
mobile_phone "1235551234"
company_name "Widgets Inc."
password "password"
end
end
Here are the relevant parts of teams_controller_spec.rb
:
require 'rails_helper'
RSpec.describe TeamsController, type: :controller do
# This should return the minimal set of values that should be in the session
# in order to pass any filters (e.g. authentication) defined in
# TeamsController. Be sure to keep this updated too.
let(:valid_session) { {} }
describe "GET #index" do
it "assigns all teams as @teams" do
user = FactoryGirl.create(:user)
team = Team.create!(name: "New Team Name", user: user)
get :index, {}, valid_session
expect(assigns(:teams)).to eq([team])
end
end
end
The test is failing:
1) TeamsController GET #index assigns all teams as @teams
Failure/Error: get :index, {}, valid_session
NoMethodError:
undefined method `authenticate' for nil:NilClass
I don't understand how I need to populate :valid_session
so that the test will pass. I thought I'd have to explicitly call an authenticate method but that might not be true. I'm trying to test the Team controller... not User authentication.
Any advice would be much appreciated.
I'd do this in your rails_helper:
module ControllerMacros
def sign_me_in
before :each do
@request.env['devise.mapping'] = Devise.mappings[:user]
@current_user = FactoryGirl.create(:user)
sign_in :user, @current_user
end
end
end
Rspec.configure do |config|
#other rspec stuff
config.include FactoryGirl::Syntax::Methods
config.extend ControllerMacros, type: :controller
config.include Devise::Test::ControllerHelpers, type: :controller
end
Then in your controller spec, (provided you're requiring your rails_helper) you can just to sign_me_in
whenever you want to be signed in and not bother about the valid_session:
RSpec.describe TeamsController, type: :controller do
sign_me_in
#etc...
end
However in your specific case you want to know who you're signed in as, so you can do this:
RSpec.describe TeamsController, type: :controller do
describe "GET #index" do
it "assigns all teams as @teams" do
user = FactoryGirl.create(:user)
team = Team.create!(name: "New Team Name", user: user)
@request.env['devise.mapping'] = Devise.mappings[:user]
sign_in :user, user
get :index
expect(assigns(:teams)).to eq([team])
end
end
end
The devise mappings line may not be required in your case, but can't say without inspecting your full app.