Ruby on rails 工厂女孩的重复联想
我正在使用fixture在RubyonRails项目上加载测试数据。我搬到了工厂女孩,但我得到了重复的协会条目 我有一个Ruby on rails 工厂女孩的重复联想,ruby-on-rails,factory-bot,Ruby On Rails,Factory Bot,我正在使用fixture在RubyonRails项目上加载测试数据。我搬到了工厂女孩,但我得到了重复的协会条目 我有一个组模型和一个值模型。组可以有多个值 另外,我用黄瓜做测试。和FactoryGirl.lint填充数据库 我的固定装置 组.yml group_1: name: "Flavour" values.yml value_1: name: "Strawberry" group: group_1 value_2: name: "Mint" group: group
组
模型和一个值
模型。组
可以有多个值
另外,我用黄瓜做测试。和FactoryGirl.lint
填充数据库
我的固定装置
组.yml
group_1:
name: "Flavour"
values.yml
value_1:
name: "Strawberry"
group: group_1
value_2:
name: "Mint"
group: group_1
value_3:
name: "Chocolate"
group: group_1
这个很好用。创建一个组
,并将3个值
附加到该组
我的工厂
groups.rb
FactoryGirl.define do
factory :group do
name "Flavour"
end
end
values.rb
FactoryGirl.define do
factory :value_1, class: :value do
name "Strawberry"
group
end
factory :value_2, class: :value do
name "Mint"
group
end
factory :value_3, class: :value do
name "Chocolate"
group
end
end
这是行不通的。Factory Girl正在创建3个组,每个组与1个值关联
这是工厂女孩的正常行为吗
此外,我还了解到use\u transactional\u fixture
应该设置为true。情况已经如此。您的价值工厂被告知将集团工厂用于其集团,集团工厂被告知创建一个名为“Flavor”的新集团。您想要做的不同之处在于,您希望集团工厂返回现有的“味道”,而不是新的味道。下面是如何做到这一点
FactoryGirl.define do
factory :group, class: :group do
name 'Flavor'
initialize_with {Group.find_or_initialize_by(name: name)}
end
end
也就是说,如果您已经有一个具有所需名称的组,请使用现有组。如上所述编写,这样就有了一个默认名称,并且在传递替代名称时,您会得到相同的“使用现有名称(如果存在)”行为。您的值工厂被告知将组工厂用于其组,并且组工厂被告知创建一个名为“Flavor”的新组。您想要做的不同之处在于,您希望集团工厂返回现有的“味道”,而不是新的味道。下面是如何做到这一点
FactoryGirl.define do
factory :group, class: :group do
name 'Flavor'
initialize_with {Group.find_or_initialize_by(name: name)}
end
end
也就是说,如果您已经有一个具有所需名称的组,请使用现有组。如上所述编写,这样就有了一个默认名称,当传递一个替代名称时,您会得到相同的“使用现有名称(如果存在)”行为。我认为您还没有真正理解使用夹具和工厂之间的概念差异
- 使用fixture,您可以在每次测试运行时将这些静态对象定义放入数据库中。它就像你的数据库已经有了一堆数据的“零”状态。感觉很好,温暖和模糊(哦,我不必设置所有的东西,太好了!)但实际上这是一个可怕的想法,因为它掩盖了空桌子造成的任何错误李>
- 使用工厂,您可以动态定义对象,并在需要时创建它们。您可以使用类似的工具来清除测试之间的任何剩余状态。每次测试都是从零开始的
FactoryGirl.lint
不填充数据库。它是一个检查工厂定义是否正确的过梁
使用factory_girl绝对没有意义,如果你只是用它创建了一堆固定装置。因此,您需要执行以下操作:
FactoryGirl.define do
factory :value do
name { ["Strawberry", "Mint", "Chocolate"].sample }
group
end
end
从夹具到工厂的一个心理障碍是你必须停止编写测试,就像你在哪里使用夹具数据:
describe "GET /users/:id" do
let!(:user){ FactoryGirl.create(:user) }
let(:json) { JSON.parse(response.body) }
before { get users_path(@user), format: :json }
it "has the correct name" do
# bad
expect(json["name"]).to eq "John Doe" # strong coupling to factory!
# good
expect(json["name"]).to eq user.name # we don't know what the factory generates.
end
end
如果必须进行一个测试,其中必须知道某个工厂值,或者某个工厂需要与某个对象关联,那么就显式地进行测试,而不是将定义弄得一团糟
let(:user) { FactoryGirl.create(:user, name: 'Max') }
let(:item) { user.items.create(FactoryGirl.attributes_for(:item)) }
it "has an awesome name" do
expect(user.name).to eq 'Max'
end
it "is associated" do
expect(item.user).to eq user
end
我认为你还没有真正理解使用固定装置和工厂在概念上的区别
- 使用fixture,您可以在每次测试运行时将这些静态对象定义放入数据库中。它就像你的数据库已经有了一堆数据的“零”状态。感觉很好,温暖和模糊(哦,我不必设置所有的东西,太好了!)但实际上这是一个可怕的想法,因为它掩盖了空桌子造成的任何错误李>
- 使用工厂,您可以动态定义对象,并在需要时创建它们。您可以使用类似的工具来清除测试之间的任何剩余状态。每次测试都是从零开始的
FactoryGirl.lint
不填充数据库。它是一个检查工厂定义是否正确的过梁
使用factory_girl绝对没有意义,如果你只是用它创建了一堆固定装置。因此,您需要执行以下操作:
FactoryGirl.define do
factory :value do
name { ["Strawberry", "Mint", "Chocolate"].sample }
group
end
end
从夹具到工厂的一个心理障碍是你必须停止编写测试,就像你在哪里使用夹具数据:
describe "GET /users/:id" do
let!(:user){ FactoryGirl.create(:user) }
let(:json) { JSON.parse(response.body) }
before { get users_path(@user), format: :json }
it "has the correct name" do
# bad
expect(json["name"]).to eq "John Doe" # strong coupling to factory!
# good
expect(json["name"]).to eq user.name # we don't know what the factory generates.
end
end
如果必须进行一个测试,其中必须知道某个工厂值,或者某个工厂需要与某个对象关联,那么就显式地进行测试,而不是将定义弄得一团糟
let(:user) { FactoryGirl.create(:user, name: 'Max') }
let(:item) { user.items.create(FactoryGirl.attributes_for(:item)) }
it "has an awesome name" do
expect(user.name).to eq 'Max'
end
it "is associated" do
expect(item.user).to eq user
end
当您尝试创建随机相关对象而不是特定对象时,FactoryGirl通常更具相关性。在您的情况下,我建议创建普通的旧ActiveRecord:g=Group.create(名称:'flavor');%w(草莓薄荷巧克力)。每个{n |值。创建(名称:n,组id:g.id)
}。您可以始终使用factory girl覆盖属性:FactoryGirl.create:Value|1,组:a|组
FactoryGirl在尝试创建随机相关对象而非特定对象时通常更相关。在您的情况下,我建议创建普通的旧ActiveRecord:g=Group.create(名称:'flavor');%w(草莓薄荷巧克力)。每个{n |值。创建(名称:n,组id:g.id)
}。您可以始终使用factory girl:FactoryGirl.create:Value|1,组:a|组
覆盖属性。其他人关于工厂和设备之间差异的注释是有效的。但是在一些测试情况下,需要使用上述技术。谢谢@elc的输入。现在我将使用它,并将max的建议贯彻到底。其他人关于工厂和固定装置之间差异的意见是有效的。但是在一些测试情况下,需要使用上述技术。谢谢@elc的输入。现在我将使用它,并将max的建议贯彻到底。谢谢你澄清这一点。我正在记下你的解释,并将在今后适当地实施