Hommer Smith
Hommer Smith

Reputation: 27862

FactoryGirl and belongs_to association when testing Rspec

I have the following model:

class Team < ActiveRecord::Base
  # Setup accessible (or protected) attributes for your model
  attr_accessible :name
  validates_presence_of :name

  belongs_to :user

end

Which is tested by:

describe Team do

  before(:each) do
    @attr = FactoryGirl.attributes_for(:team)
  end

  it "should belong to a user" do
    @team = Team.create!(@attr)
    @team.should belong_to(:user)
  end
end

And I have the following factories:

FactoryGirl.define do
  factory :team do
    name 'Dream Team'
    sport
    user
  end
end

FactoryGirl.define do
  factory :user do
    name 'Test User'
    last_name 'Last Name'
    email '[email protected]'
    password 'changeme'
    password_confirmation 'changeme'
  end
end

When I test the spec, I get the following failure:

1) Team should belong to a user Failure/Error: @team = Team.create!(@attr) ActiveRecord::StatementInvalid: SQLite3::ConstraintException: teams.user_id may not be NULL: INSERT INTO "teams" ("created_at", "name", "sport_id", "updated_at", "user_id") VALUES (?, ?, ?, ?, ?)

Why is that? In the docs it says that to set an association you can just write the Factory name, in my case is user.

Thanks

Upvotes: 4

Views: 4386

Answers (2)

Kevin Behan
Kevin Behan

Reputation: 496

You should not be using before(:each) with FactoryGirl and Rspec, in fact a more elegant way of creating this test, according to The Rails 4 Way Chapter 21, is by using let(:team) { FactoryGirl.create(:team } prior to your it statements

this allows you to not use so many instance variables, if desired I can provide an example if this explanation is not sufficient

Upvotes: 0

Marcelo De Polli
Marcelo De Polli

Reputation: 29301

FactoryGirl.attributes_for will give you a hash containing the attributes for the specified model only, not including association attributes -- in your case, user_id.

That will throw up errors in case user_id is a required field and you're trying to create an instance of Team by using FactoryGirl.create(attributes_for(:team)).

However, if you use FactoryGirl.create(:team) it should give you a valid instance of Team.

Upvotes: 4

Related Questions