How can I share the factories that I have in a GEM and use it in other project?

后端 未结 2 1326
广开言路
广开言路 2020-12-15 07:05

I have a gem that includes some Factories. The gem looks something like:

.
├── Gemfile
├── Gemfile.lock
├── README.md
├── Rakefile
├── db
├── lib
│   ├── mo         


        
相关标签:
2条回答
  • 2020-12-15 07:37

    An alternative to require-ing each factory file as suggested in the other answer, is to update the FactoryBot.definition_file_paths configuration.

    In your gem defining the factories:

    Create a file which will resolve the factory path:

    # lib/my_gem/test_support.rb
    
    module MyGem
      module TestSupport
        FACTORY_PATH = File.expand_path("../../spec/factories", __dir__)
      end
    end
    

    In you app / gem using the factories from the other gem:

    # spec/spec_helper.rb or similar
    
    require "my_gem/test_support"
    
    FactoryBot.definition_file_paths = [
      MyGem::TestSupport::FACTORY_PATH,
      # Any other paths you want to add e.g.
      # Rails.root.join("spec", "factories")
    ]
    
    FactoryBot.find_definitions
    

    The advantage of the definition_file_paths solution is that other functionality like FactoryBot.reload will work as intended.

    0 讨论(0)
  • 2020-12-15 07:53

    The problem is that you probably don't expose the spec folder (and herewith the factories) in the load path. Which, in general, is the right thing to do. Check you *.gemspec, you probably have something like:

    s.require_paths = ["lib"]
    

    This means only files under the lib directory can be required by other projects using your gem. See http://guides.rubygems.org/specification-reference/#require_paths=

    So to solve your problem, you'd need to place a file inside the lib folder which 'knowns' where your factories are and requires those. So in you case, create a file lib/<your gem name>/factories.rb and add:

    GEM_ROOT = File.dirname(File.dirname(File.dirname(__FILE__)))
    
    Dir[File.join(GEM_ROOT, 'spec', 'factories', '*.rb')].each { |file| require(file) }
    

    In the other Project load the factories with:

    require '<your gem name>/factories'

    Works fine for me. The only thing I havn't figured out yet is how to namespace your factories. Not sure if factory girl allows this.

    0 讨论(0)
提交回复
热议问题