简体   繁体   English

FactoryBot 如何访问多个工厂中的相同变量

[英]FactoryBot how to access same var in multiple factories

I would like to know how to use the same array in multiple factories using rspec in Rail, does any body know a good solution?我想知道如何在 Rail 中使用 rspec 在多个工厂中使用相同的数组,有没有人知道一个好的解决方案?

Currently, I have the array bellow that I have to repeat in every factory that needs to enter the lat/log.目前,我有下面的数组,我必须在每个需要输入纬度/日志的工厂中重复。

coordinates = [
  {latitude: 50.0, longitude: -100.0},
  {latitude: 50.1, longitude: -100.1},
  {latitude: 50.2, longitude: -100.2},
  {latitude: 50.3, longitude: -100.3}
]

Then, to attribute a value I do a .sample and insert into the field:然后,要属性一个值,我做一个 .sample 并插入到字段中:

coordinate = coordinates.sample
latitude { coordinate[:latitude] }
longitude { coordinate[:longitude] }

I would like to keep these coordinates "padronized" so I can be sure where it is going to be.我想保持这些坐标“padronized”,所以我可以确定它会在哪里。 That's because later down the road I check if they fall inside a polygon or not.那是因为稍后我会检查它们是否落在多边形内。

I am currently using: rails 5.2.3 rspec-rails 3.8.0 factory_bot_rails 5.0.1我目前正在使用:rails 5.2.3 rspec-rails 3.8.0 factory_bot_rails 5.0.1

I would like to keep these coordinates "padronized" so I can be sure where it is going to be.我想保持这些坐标“padronized”,所以我可以确定它会在哪里。 That's because later down the road I check if they fall inside a polygon or not.那是因为稍后我会检查它们是否落在多边形内。

FactoryBot is about avoiding having fixed testing data. FactoryBot 旨在避免拥有固定的测试数据。 Instead, write a factory which will generate valid coordinates.相反,编写一个将生成有效坐标的工厂。

FactoryBot.define do
  factory :coordinates, class: "Hash" do
    latitude { rand(-180.0..180.0) }
    longitude { rand(-180.0..180.0) }

    initialize_with do
      attributes
    end
  end
end

Rather than hard coding your coordinates so they fit inside a hard coded polygon, generate a polygon which contains the coordinates as you need.与其对坐标进行硬编码以使它们适合硬编码多边形,不如生成一个包含您需要的坐标的多边形。 Do this with a trait .trait 来做这件事。 Traits let different tests use the same factory in different ways without any risk of interfering with each other. Traits 让不同的测试以不同的方式使用同一个工厂,而不会有任何相互干扰的风险。

factory :polygon do
  # normal polygon attributes go here

  trait :contains_coordinates do
    transient do
      coordinates { build(:coordinates) }
    end
      
    # set up the attributes so they contain the coordinate
  end
end

Then ask for a polygon which contains a coordinate when you need it .然后在需要时请求一个包含坐标的多边形。

describe '#contains_coordinates?' do
  subject {
    polygon.contains_coordinates?(coordinates)
  }

  context 'when the coordinates are inside the polygon' do
    let(:coordinates) { build(:coordinates) }
    let(:polygon) {
      build(:polygon, :contains_coordinates, coordinates: coordinates)
    }

    it { is_expected.to be true }
  end
end

This can also work the other way around, add a trait to the coordinates factory which is guaranteed to be inside a polygon.这也可以反过来工作,向coordinates工厂添加一个特征,保证在多边形内。

If you have any data that you don't want to be changed, the simplest approach is to basically treat it as fixtures.如果您有任何不想更改的数据,最简单的方法是基本上将其视为固定装置。 You can either use Rails' own fixtures mechanism (see documentation in the official Rails Guides: https://guides.rubyonrails.org/testing.html#the-low-down-on-fixtures ) or build your own simple fixture importer:您可以使用 Rails 自己的装置机制(请参阅官方 Rails 指南中的文档: https : //guides.rubyonrails.org/testing.html#the-low-down-on-fixtures )或构建自己的简单装置导入器:

# spec/fixtures/coordinates.yml
- latitude: 50.0
  longitude: -100.0
- latitude: 50.1
  longitude: -100.1
- latitude: 50.2
  longitude: -100.2
- latitude: 50.3
  longitude: -100.3
# spec/support/fixtures_helper

module FixturesHelper
  def coordinates
    YAML.load_file(Rails.root.join('spec', 'fixtures', 'coordinates.yml'))
  end
end

RSpec.configure do |config|
  config.include FixturesHelper
end
# in some test

it 'does something with coordinates' do
  expect(do_something_with(coordinates[0]).to eq some_result
end

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM