如何使FactoryGirl.create影响另一个记录的属性?
在order.save
商店应用程序中,通常在预订产品之后, bookings_controller创建操作会执行order.save
,而order.save
又会激活必要的before_save方法order.sum_of_all_bookings
。
在为查看订单列表的管理员构建RSpec测试时,进行预订不会更改订单总数。 索引在浏览器中有效。
require 'rails_helper' RSpec.feature 'Admin can oversee orders' do let(:admin) { FactoryGirl.create(:user, :admin) } let(:customer) { FactoryGirl.create( :user ) } let!(:order_1) { FactoryGirl.create( :order, customer: customer ) } let!(:booking_1) { FactoryGirl.create( :booking, product_name: 'Honingpot', product_quantity: 1, product_price: '5,00', order: order_1 ) } let!(:order_2) { FactoryGirl.create( :order, customer: customer ) } let!(:booking_2) { FactoryGirl.create( :booking, product_name: 'Streekpakket', product_quantity: 2, product_price: '10,00', order: order_2 ) } before do order_1.sum_all_bookings order_2.sum_all_bookings login_as(admin) visit orders_path end scenario 'with success' do within('table#paid') do expect(page).to have_content '5,00' expect(page).to have_content '10,00' end end end
在块之前不起作用。
工厂女孩创建后也没有:
FactoryGirl.define do factory :booking do product_name 'Honingpot' product_quantity '1' product_price '3,99' order after(:create) { |booking| booking.order.save } # booking.order.sum_all_bookings, also not working end end
RSpec打印订单中的预订,但订单总数不变。
如何订单总和预订?
或者更一般地说:
如何使FactoryGirl.create
影响另一个记录的属性?
清理您的规格
首先,您的规格中有太多的工厂配置。 FactoryGirl可以将您的创建和设置从您的规范中移开 。
这不会直接解决您的问题,但这些步骤将使您的测试过程更清晰,更简单,更快捷。
1. Faker Gem
要开始改造,请继续添加faker gem,以便您可以轻松地为工厂生成有用的随机数据。
FactoryGirl.define do factory :booking do product_name { Faker::Commerce.product_name } product_quantity { Faker::Number.number(2) } product_price Faker::Number.decimal(2) order end end
你去,一些准备好的预订工厂准备使用。
2.特质
它们是在某些情况下调整工厂的好方法。 绝对在文档中阅读更多关于它们的内容 。
FactoryGirl.define do factory :order do customer trait :with_bookings do after(:create) do |order| order.bookings << create_list(:booking, 2) end end end end
所以现在您可以轻松创建包含或不包含预订的订单:
let(:order_with_bookings) { create(:order, :with_bookings) }
3.更清晰的语法
您可以FactoryGirl
语法,只需create(:order)
。 完成这些步骤后,您应该拥有更清洁的测试环境。
解决回调问题
据我了解,你设置你的回调如下:
class Order has_many :bookings before_save :update_order_cache def update_order_cache # calculation of the total bookings sum end end class Booking belongs_to :order end
但是你应该反过来做,在产品创建或更新后,应该触发订单上的回调:
class Order has_many :bookings def update_order_cache # calculation of the total bookings sum end end class Booking belongs_to :order after_save do order.update_order_cache end end
如果该字段永远不应为空,您还可以向总和添加默认值。
validates :sum_field, presence: true, default: '0.0'
这应该包括你。 干杯!