Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FactoryGirl: Factory not registered

I work on a project with a structure like:

projects/warehouse/core
projects/warehouse/products/bottles
projects/warehouse/products/boxes

In this project, the application logic, gems, etc. are all in the core application. I have boxes set up for rspec like such:

projects/warehouse/products/boxes/spec
    /factories
    /models

The factories directory contains cubics.rb:

FactoryGirl.define do
  factory :cubic
    id 1
    dimension 12
  end
end

The models directory contains cubic_spec.rb:

require 'spec_helper'

describe Boxes::Cubic do
  it "has a valid factory" do
    FactoryGirl.create(:cubic).should be_valid
  end
end

The Cubic model is located in products/boxes/app/models/boxes/cubic.rb.

module Boxes
  class Cubic < BoxExBase
    self.table_name = 'containers'
    #validation stuff goes here
  end
end

Simple and straightforward. When I execute rspec ../products/boxes/spec/models/cubic_spec.rb I get the ArgumentError: Factory not registered: cubic. I've tried requiring factory_girl_rails in the spec_helper.rb. I've tried modifying the spec_helper.rb w/

FactoryGirl.definition_file_paths << File.join(File.dirname(__FILE__), 'factories')
FactoryGirl.find_definitions

The gemfile in the core contains gem 'factory_girl_rails' in the development, test groups. I've even tried getting the factory to raise an error, but that doesn't even happen. Therefore, the factory doesn't appear to even be getting loaded. What do I need to do to get this factory loaded and registered?

like image 827
CitizenX Avatar asked Oct 10 '13 14:10

CitizenX


2 Answers

You need to help the dummy app (or the rails console) out, since FactoryGirl is going to look in Rails.root, which is spec/dummy.

So, from a console launched in spec/dummy for example just do this:

FactoryGirl.definition_file_paths = %w(../factories)
FactoryGirl.find_definitions
# You can use this line to see what factories are loaded
# FactoryGirl.factories

For your particular case, you'll need to change the actual locations, but where you are, if FactoryGirl isn't finding your factories, it's because it doesn't know where to look.

To be specific: Here is what I did. My needs were as follows - I needed to run rspec from the Gem root directory. But I also need to be able to run the rails console from the embedded dummy project and access Factory girl for convenient test object creation during development.

TLDR Add this code into your dummy app's application.rb

 console do
   FactoryGirl.definition_file_paths << Pathname.new("../factories")
   FactoryGirl.definition_file_paths.uniq!
   FactoryGirl.find_definitions
 end

├── spec
│   ├── dummy
│   │   ├── app
│   │   ├── bin
│   │   ├── config
│   │   │   ├── environments
│   │   │   ├── initializers
│   │   │   ├── locales
│   │   │   ├── application.rb << This is the file to add the lines in.

The releveant bits of my application layout looks like

├── app
├── bin
├── config
├── lib
├── spec
│   ├── dummy
│   │   ├── app
│   │   ├── bin
│   │   ├── config
│   │   │   ├── environments
│   │   │   ├── initializers
│   │   │   ├── locales
│   │   │   ├── application.rb
│   │   │   ├── boot.rb
│   │   │   ├── database.yml
│   │   │   ├── environment.rb
│   │   │   └── routes.rb
...
│   ├── factories
│   │   └── models
│   │       └── api_requests.rb
│   ├── lib
│   │   ├── controllers
│   │   │   ├── controller_spec.rb
│   │   │   └── session__spec.rb
│   │   └── my_spec.rb
│   ├── support
│   └── vcr
│   ├── spec_helper.rb

├── Gemfile
├── Gemfile.lock
├── mygem.gemspec  << this is the file to include the factory-girl-rails gem

I'm including the factory-girl-rails gem in my gemspec only and only in that location. Nothing in my Gemfile, and nothing in the Gemfile for the dummy app.

  s.add_development_dependency 'rspec-rails'
  s.add_development_dependency 'capybara'
  s.add_development_dependency 'factory_girl_rails'
  s.add_development_dependency 'shoulda'
  s.add_development_dependency 'vcr'
  s.add_development_dependency 'byebug'
  s.add_development_dependency 'better_errors'
  s.add_development_dependency 'binding_of_caller'
like image 87
Ashley Raiteri Avatar answered Nov 16 '22 23:11

Ashley Raiteri


Here's how we got around it. As @Vinh Tran suggested, factory_girl_rails does need to be within the Gemfile of the app that you're working on as such:

group :development, :test do
  gem 'rspec-rails'
  gem 'factory_girl_rails'
end

Additionally, the dummy app needs to be located under the /spec directory, although at this point, it doesn't appear to be populated with actual models, etc.

Finally, the rspec command needs to issued from the boxes directory as opposed to core directory. All of these things combined have allowed us to successfully register a factory and have successful test runs.

like image 27
CitizenX Avatar answered Nov 16 '22 21:11

CitizenX