Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rspec 在Rails中创建与FactoryBot/FactoryGirl的关联_Rspec_Factory Bot - Fatal编程技术网

Rspec 在Rails中创建与FactoryBot/FactoryGirl的关联

Rspec 在Rails中创建与FactoryBot/FactoryGirl的关联,rspec,factory-bot,Rspec,Factory Bot,我有三个相互关联的工厂:Country类有States类,States有City类 countries.rb FactoryBot.define do factory :country do name { Faker::Address.unique.country } end end states.rb FactoryBot.define do factory :state do association :country name { Faker::Address.

我有三个相互关联的工厂:
Country
类有States类,
States
City

countries.rb

FactoryBot.define do
factory :country do
    name { Faker::Address.unique.country }
  end
end
states.rb

FactoryBot.define do
factory :state do
    association :country
    name { Faker::Address.state }
  end
end
cities.rb

   FactoryBot.define do
    factory :city do
        association :state
        name { Faker::Address.city }
      end
    end
在我的规范中,我想实例化特定的对象

  before(:each) do
    create(:city, name:"Buffalo")
    create(:state, name:"New York")
    create(:country, name:"United States")

  end

我如何将美国与纽约州联系起来,将纽约州与布法罗市联系起来

可以将每个对象作为另一个工厂的属性传递

before(:each) do
  country = create(:country, name:"United States")
  state = create(:state, name:"New York", country: country)
  create(:city, name:"Buffalo", state: state)
end
但这使得您无法访问这些测试对象。相反,为每个对象使用一个

let!(:country) { create(:country, name:"United States") }
let!(:state) { create(:state, name:"New York", country: country) }
let!(:city) { create(:city, name:"Buffalo", state: state) }
现在,您可以在示例中参考
国家
城市
。除非您特别需要为测试创建对象,否则您可能应该使用
let
,并允许根据需要创建对象

最后,我们可以通过反转这个来节省大量的工作。创建一个城市,然后从城市中检索州,从州中检索国家

let(:city) { create(:city) }
let(:state) { city.state }
let(:country) { state.country }
您可以在测试中引用
city.name
,而不是指定确切的名称。比如说

let(:city) { create(:city) }
let(:state) { city.state }
let(:country) { state.country }

describe '#find_city' do
  it 'finds a city by name' do
    expect( country.find_city(city.name) ).to eq city
  end
end

describe '#find_state' do
  it 'finds a state by name' do
    expect( country.find_state(state.name) ).to eq state
  end
end

这是一个很好的解释。谢谢我有一个方法可以检查一个城市是否存在,如果它不存在,它就会创建它。因此,我需要创建一个预先存在的城市来检查边缘情况。对于这种情况,我不需要使用!对的我需要清理工厂吗?Thanks@lost9123193
按需运行<代码>让在每个示例之前运行。每个示例只运行一次并缓存结果,因此您只能得到一个城市。如果您需要一个已经存在的城市进行测试,请使用
let
,或在{city}之前使用
。不,没有必要清理您的数据库,rspec应该为您这样做。每个示例在一个事务中运行,并在最后回滚。