dennismonsewicz
dennismonsewicz

Reputation: 25552

FactoryGirl issues with associations in Rspec/Rails

Here is the method I am testing:

class User < ActiveRecord::Base
  has_many :sports, :through => :user_sports, order: "user_sports.created_at", class_name: "Sport"
  has_many :user_sports

  def primary_sport
    return nil if user_sports.blank?
    user_sports.primary_only.first.sport
  end
end

User Factory;

FactoryGirl.define do
  sequence(:email) do |n|
    "user#{n}@example.com"
  end

  factory :user do
    email
    first_name Faker::Name.first_name
    last_name Faker::Name.last_name
    password "password"
    password_confirmation "password"
    agreed_to_age_requirements true
    username "testing123"
    state "AL"
    city_id 201
    school_id 20935
    handedness "Left"
    customer_id { "#{rand(1000)}" }

    sports {[create(:sport)]}

    after(:create) do |user, elevator|
      user.subscriptions << create(:subscription)
      user.roles << create(:role)
    end
  end

  factory :athlete, class: "Athlete", parent: :user do
    type "Athlete"
    recruit_year "2016"
  end
end

Here is my test:

require 'spec_helper'

describe User do
  describe "associations" do
    it { should have_and_belong_to_many(:roles) }
    it { should belong_to(:account_type) }
    it { should belong_to(:primary_sport).class_name("Sport") }
    it { should belong_to(:school) }
    it { should belong_to(:city) }
    it { should belong_to(:hometown) }
    it { should have_many(:social_actions) }
    it { should have_one(:invitation) }
    it { should have_many(:authorizations) }
    it { should belong_to(:user_type) }
    it { should have_and_belong_to_many(:positions).class_name "SportPosition" }
    it { should have_many(:sports).through(:user_sports) }
    it { should have_many(:user_sports) }
    it { should have_many :contributorships }
    it { should have_many(:managed_athletes).through(:contributorships) }
    it { should have_and_belong_to_many(:subscriptions) }
  end

  describe "nested attributes" do
    it { should accept_nested_attributes_for(:user_sports) }
    it { should accept_nested_attributes_for(:subscriptions) }
  end

  describe "validations" do
    it { should validate_presence_of(:email) }
    it { should validate_uniqueness_of(:email) }
    it { should allow_value("[email protected]").for(:email) }
    it { should_not allow_value("test.com").for(:email) }
  end

  describe "instance methods" do
    before :each do
      @user = create(:user, sports: [])
      @school_admin_role = create(:role, name: "School Admin")
      @contributor_role = create(:role, name: "Contributor")
    end

    describe "#my_athletes_path" do
      it "returns a school admin path if the user has the role of School Admin" do
        @user.roles << @school_admin_role
        @user.my_athletes_path.should eq school_admin_athletes_path
      end

      it "returns a school admin path if the user has the role of Contributor" do
        @user.roles << @contributor_role
        @user.my_athletes_path.should eq contributor_dashboard_path
      end

      it "returns nil if the user has no Contributor or School Admin role" do
        @user.my_athletes_path.should be_nil
      end
    end

    describe "#first_time_login?" do
      it "will evalute true if the user has logged in only once" do
        @user.sign_in_count = 1
        @user.save
        @user.first_time_login?.should be_true
      end
    end

    describe "#confirmation_required?" do
      it "returns false" do
        @user.confirmation_required?.should be_false
      end
    end

    describe "#primary_sport", focus: true do
      context "when user has no primary sport" do
        it "returns nil" do
          @user.primary_sport.should be_nil
        end
      end

      context "when user has a primary sport" do
        it "returns sport object" do
          @user.sports << create(:sport)
          @user.primary_sport.should eq @user.sports.first
        end
      end
    end


  end

end

This is the error I am receiving:

Failure/Error: @user.primary_sport.should eq @user.sports.first
     NoMethodError:
       undefined method sport for nil:NilClass

This is because when the user_sport association is created in the User Factory, the primary column is being set to false. Not sure how to fix this. Any help is greatly appreciated! Also, sorry for the ignorance on the TDD front, Im a newb

Upvotes: 0

Views: 154

Answers (1)

Peter Goldstein
Peter Goldstein

Reputation: 4545

Couldn't you just add the following to your after(:create) block in the User factory:

us = user.user_sports.first
us.primary = true
us.save

That would ensure the association gets the primary flag.

Upvotes: 1

Related Questions