0

我想知道如何在 Rail 中使用 rspec 在多个工厂中使用相同的数组,有没有人知道一个好的解决方案?

目前,我有下面的数组,我必须在每个需要输入纬度/日志的工厂中重复。

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}
]

然后,为了赋予一个值,我做了一个 .sample 并插入到该字段中:

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

我想保持这些坐标“padronized”,这样我就可以确定它会在哪里。那是因为稍后我会检查它们是否落在多边形内。

我目前正在使用:rails 5.2.3 rspec-rails 3.8.0 factory_bot_rails 5.0.1

4

2 回答 2

2

我想保持这些坐标“padronized”,这样我就可以确定它会在哪里。那是因为稍后我会检查它们是否落在多边形内。

FactoryBot 旨在避免拥有固定的测试数据。相反,编写一个将生成有效坐标的工厂。

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

与其硬编码您的坐标以便它们适合硬编码的多边形,不如生成一个包含您需要的坐标的多边形。使用trait执行此操作。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

然后在需要时询问包含坐标的多边形。

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

这也可以反过来工作,向coordinates工厂添加一个保证在多边形内的特征。

于 2020-10-03T04:13:44.667 回答
1

如果您有任何不想更改的数据,最简单的方法是基本上将其视为固定装置。您可以使用 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
于 2020-10-03T13:15:10.053 回答