FactoryGirl与Rspec / Rails中的关联有关

时间:2013-11-07 19:07:45

标签: ruby-on-rails rspec factory-bot

以下是我正在测试的方法:

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

用户工厂;

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

这是我的测试:

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("test@test.com").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

这是我收到的错误:

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

这是因为在用户工厂中创建user_sport关联时,primary列设置为false。不知道如何解决这个问题。任何帮助是极大的赞赏!此外,对于TDD前线的无知感到抱歉,我是一个新手

1 个答案:

答案 0 :(得分:1)

您是否只能将以下内容添加到用户工厂中的after(:create)块:

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

这将确保关联获得主要标志。