FactoryGirl: Factory not registered

2019-04-18 18:21发布

问题:

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?

回答1:

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'


回答2:

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.



回答3:

I got this when my spec didn't end with _spec.rb. RubyMine ran the unit test without any problem, and everything worked except for Factory Girl.



回答4:

2 things you can try:

  • putting the gem 'factory_girl_rails' inside the boxes app
  • create a sample rspec inside the core with factory and run it

I think your boxes app doesn't load the gems from the core, it just load the business logic