Using fixtures with factory_girl
Asked Answered
T

2

9

When building the following factory:

Factory.define :user do |f|
  f.sequence(:name) { |n| "foo#{n}" }
  f.resume_type_id { ResumeType.first.id }
end

ResumeType.first returns nil and I get an error.

ResumeType records are loaded via fixtures. I checked using the console and the entries are there, the table is not empty.

I've found a similar example in the factory_girl mailing list, and it's supposed to work.

What am I missing? Do I have to somehow tell factory_girl to set up the fixtures before running the tests?

This is what my test_helper looks like:

ENV["RAILS_ENV"] = "test"
require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
require 'test_help'

class ActiveSupport::TestCase
  self.use_transactional_fixtures = true
  self.use_instantiated_fixtures  = false
  fixtures :all
end
Tripartite answered 28/4, 2010 at 19:43 Comment(7)
Why use a mixture of factories and fixtures? Factories replace fixtures.Million
How does your test_helper.rb looks like?Coppola
I'm using fixtures for fixed data that won't be changed by anyone after it's seeded.Tripartite
I added test_helper.rb to the questionTripartite
In answer to the question of "why use a mixture of factories and fixtures", in my case? To get from one to the other in small steps.Gardol
@GraemeMathieson agreed! Another use case is when you want "singleton" or "memoized" fixtures whose id remains constant across references within the same test. See also github.com/thoughtbot/factory_girl/issues/148Aircrew
In answer to the question of "why use a mixture of factories and fixtures", in my case? To delegate expensive construction of models to the much faster fixture system, in order to reduce the time tests take to run.Pilpul
G
7

My solution to this was to create a db/seeds.rb file which contained model code to generate my seed data:

# Create the user roles
Role.create(:name => "Master", :level => 99)
Role.create(:name => "Admin", :level => 80)
Role.create(:name => "Editor", :level => 40)
Role.create(:name => "Blogger", :level => 30)
Role.create(:name => "User", :level => 0)

And then include it in my spec_helper.rb:

ENV["RAILS_ENV"] = 'test'
require File.expand_path(File.join(File.dirname(__FILE__),'..','config','environment'))
require 'spec/autorun'
require 'spec/rails'
require "#{Rails.root}/db/seeds.rb"

(To be fair, I haven't managed to get autospec to play nice with this yet as it keeps duplicating my seed data, but I haven't tried all that hard either.)

This also has the benefit of being Rails 3 ready and working with the rake db:seed task.

Grindelia answered 30/4, 2010 at 3:41 Comment(1)
Your best bet is to create an idempotent db/seeds.rb file, so no matter how often it's run, it still gets towards the same end state. In your example, I'd do: Role.find_or_create_by_name(:name => "Master", :level => 99).Gardol
D
0

Another option is to add seed.rb in your test or spec directory and require it in your helper file before your factories:

require File.expand_path(File.dirname(__FILE__) + "/seed")
require File.expand_path(File.dirname(__FILE__) + "/factories")

Rails 2.3

Dissuasion answered 7/11, 2011 at 16:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.