Skip to content

Testing all Factories (with RSpec)

Ben Linton edited this page Apr 23, 2015 · 23 revisions

IMPORTANT: This functionality is no longer necessary for newer versions of FactoryGirl that now support FactoryGirl.lint

To make sure that your factories are valid you can automatically test all of them with:

# /spec/support/factories_spec.rb

# If using RSpec 2.x (or if not using Rails), require `spec_helper` instead
require 'rails_helper' 

# If using RSpec 2.x, remove `RSpec.`
RSpec.describe "Factory Girl" do
  FactoryGirl.factories.map(&:name).each do |factory_name|
    describe "#{factory_name} factory" do

      # Test each factory
      it "is valid" do
        factory = FactoryGirl.build(factory_name)
        if factory.respond_to?(:valid?)
          # the lamba syntax only works with rspec 2.14 or newer;  for earlier versions, you have to call #valid? before calling the matcher, otherwise the errors will be empty
          expect(factory).to be_valid, lambda { factory.errors.full_messages.join("\n") }
        end
      end

      # Test each trait
      FactoryGirl.factories[factory_name].definition.defined_traits.map(&:name).each do |trait_name|
        context "with trait #{trait_name}" do
          it "is valid" do
            factory = FactoryGirl.build(factory_name, trait_name)
            if factory.respond_to?(:valid?)
              expect(factory).to be_valid, lambda { factory.errors.full_messages.join("\n") }
            end
          end
        end
      end

    end
  end
end

Guard (optional)

If you'd like to use Guard RSpec to automatically rerun your factory tests whenever you save a factory:

# /Guardfile
guard :rspec, cmd: 'bundle exec rspec' do

  # Watch factories
  watch(%r{^spec/factories/(.+)\.rb$}) { "spec/support/factories_spec.rb" }

  # ...

end
Clone this wiki locally