本文介绍了如何共享我在 GEM 中拥有的工厂并在其他项目中使用它?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

.├── Gemfile├── Gemfile.lock├── README.md├── Rakefile├── 数据库├── 库│ ├──模型│ │ ├── users.rb├── pkg├── core.gemspec├── 规格│ ├── 工厂│ │ └── users.rb│ ├── 灯具│ ├── 帮手│ ├── 整合│ ├── spec_helper.rb│ ├── 支持│ ││ └── 单位│ └── users_spec.rb└── 任务

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

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

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

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

需要'rubygems'需要捆绑程序/设置"Bundler.require(:default, :development)ENV['RACK_ENV'] ||=' '测试'需要机架/测试"需要 File.expand_path('../../config/environment', __FILE__)RSpec.configure 做 |config|config.mock_with :rspecconfig.expect_with :rspecconfig.raise_errors_for_deprecations!config.include FactoryGirl::Syntax::Methods结尾需要水豚/rspec"Capybara.configure 做 |config|config.app = Test::App.newconfig.server_port = 9293结尾

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

需要'spec_helper'描述 App::UsersController 做包括机架::测试::方法定义应用程序应用::API结尾描述/用户/我"做上下文使用无效的访问令牌"做之前(:每个)做获取/api/v2/users/me"用户 = 构建(:用户)结尾它返回 401 错误代码"期望(last_response.status).to eq(401)期望(用户).to eq(nil)结尾结尾结尾结尾

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

我不断收到此错误:

 失败/错误:user = build(:user)参数错误:工厂未注册:用户

任何帮助将不胜感激,因为我一直在为此而苦苦挣扎.

解决方案

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

在您定义工厂的 gem 中:

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

# lib/my_gem/test_support.rb模块 MyGem模块测试支持FACTORY_PATH = File.expand_path("../../spec/factories", __dir__)结尾结尾

在你的应用程序/gem 中使用另一个 gem 的工厂:

# spec/spec_helper.rb 或类似的需要my_gem/test_support"FactoryBot.definition_file_paths = [MyGem::TestSupport::FACTORY_PATH,# 您要添加的任何其他路径,例如# Rails.root.join("spec", "factories")]FactoryBot.find_definitions

definition_file_paths 解决方案的优势在于 FactoryBot.reload 等其他功能将按预期工作.

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

.
├── 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

Now i'm using the gem in another Ruby project (Grape) by adding something like gem 'core', git: 'https://url.git'.

Now everything is working fine as I can use User model from Grape project.

However I want to use the factories (users) so I can write further integration tests for Grape project.

In Grape project, in spec_helper.rb it looks like:

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

Now my test 'users_spec.rb' looks like:

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

Now when I try to run the test using rspec spec/api/users_spec.rb I get :

I keep getting this error:

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

Any help would be appreciated as I've been struggling for this.

解决方案

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.

这篇关于如何共享我在 GEM 中拥有的工厂并在其他项目中使用它?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 14:21