我如何分享我在创业板上的工厂并在其他项目中使用它?

我有一个包含一些工厂的gem。 gem看起来像:

. ├── Gemfile ├── Gemfile.lock ├── README.md ├── Rakefile ├── db ├── lib │ ├── models │ │ ├── users.rb ├── pkg ├── core.gemspec ├── spec │ ├── factories │ │ └── users.rb │ ├── fixtures │ ├── helpers │ ├── integration │ ├── spec_helper.rb │ ├── support│ │ │ └── unit │ └── users_spec.rb └── tasks 

现在我在另一个Ruby项目(Grape)中使用gem来添加类似gem 'core', git: 'https://url.git'

现在一切正常,因为我可以使用Grape项目的User模型。

但是我想使用工厂( users ),所以我可以为Grape项目编写进一步的集成测试。

在Grape项目中,在spec_helper.rb它看起来像:

 require 'rubygems' require 'bundler/setup' Bundler.require(:default, :development) ENV['RACK_ENV'] ||= 'test' require 'rack/test' require File.expand_path('../../config/environment', __FILE__) RSpec.configure do |config| config.mock_with :rspec config.expect_with :rspec config.raise_errors_for_deprecations! config.include FactoryGirl::Syntax::Methods end require 'capybara/rspec' Capybara.configure do |config| config.app = Test::App.new config.server_port = 9293 end 

现在我的测试’users_spec.rb’看起来像:

 require 'spec_helper' describe App::UsersController do include Rack::Test::Methods def app App::API end describe "/users/me" do context "with invalid access token" do before(:each) do get "/api/v2/users/me" user = build(:user) end it 'returns 401 error code' do expect(last_response.status).to eq(401) expect(user).to eq(nil) end end end end 

现在,当我尝试使用rspec spec/api/users_spec.rb运行测试时,我得到:

我一直收到这个错误:

  Failure/Error: user = build(:user) ArgumentError: Factory not registered: user 

任何帮助都会受到赞赏,因为我一直在努力。

根据另一个答案中的建议, require每个工厂文件的替代方法是更新FactoryBot.definition_file_paths配置。

在定义工厂的gem中:

创建一个将解析工厂路径的文件:

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

在你的app / gem中使用来自其他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 eg # Rails.root.join("spec", "factories") ] FactoryBot.find_definitions 

definition_file_paths解决方案的优点是FactoryBot.reload等其他function可以按预期工作。

问题是您可能不会在加载路径中公开spec文件夹(以及工厂)。 一般来说,这是正确的做法。 检查你*.gemspec ,你可能有类似的东西:

 s.require_paths = ["lib"] 

这意味着只有使用gem的其他项目才能要求lib目录下的文件。 请参阅http://guides.rubygems.org/specification-reference/#require_paths=

因此,要解决您的问题,您需要在lib文件夹中放置一个文件,该文件夹“知道”您的工厂所在的位置并且需要这些文件。 所以在你的情况下,创建一个文件lib//factories.rb并添加:

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

在另一个项目中加载工厂:

require '/factories'

对我来说很好。 我唯一没想到的是如何命名你的工厂。 不确定工厂女孩是否允许这样做。