I am modeling a complex buying process in Rails that converts Requisitions into Orders. I use FactoryGirl to do my testing, and everything is fine until I try to check the OrderLineItem, which depends on the order and quote, each of which depends on other objects, etc ....
The test being tested checks the behavior on the OrderLineItem affected by the Product, which is a few associations above the chain.
Is there a good way to customize FactoryGirl so that I can easily create OrderLineItems and also dictate the behavior of the objects above in the chain without factoring each object one at a time?
Here is my graph object:
class Requisition has_many :requisition_line_items has_many :orders end class RequisitionLineItem belongs_to :requisition belongs_to :product has_many :quotes end class Quote belongs_to :line_item belongs_to :vendor has_one :order_line_item end class Order belongs_to :requisition belongs_to :vendor has_many :order_line_items end class OrderLineItem belongs_to :order belongs_to :quote has_many :assets end class Asset belongs_to :order_line_item belongs_to :product end class Product has_many :assets end class Vendor has_many :orders end
Apparently, the complex model allows you to convert a purchase βofferβ into one or more actual orders based on quotes from suppliers, and when the goods arrive, they are assigned asset tags. Then the assets themselves can be tied to the order and the supplier for support later.
This is my OrderLineItem specification, I have a rather complicated setup:
describe '#requires_tag?' do let(:product) { FactoryGirl.create :product, requires_tag: false } let(:purchase_requisition) { FactoryGirl.create :purchase_requisition } let(:line_item) { FactoryGirl.create :line_item, purchase_requisition: purchase_requisition, product: product } let(:quote) { FactoryGirl.create :quote, line_item: line_item, unit_price: 0 } subject { FactoryGirl.build :order_line_item, quote: quote } context 'when neither product nor price require a tag' do its(:requires_tag?) { should be_false } end context 'when product requires a tag' do let(:product) { FactoryGirl.create :product, requires_tag: true } its(:requires_tag?) { should be_true } end end
Do I really need myriad let instructions, or is there a better way to create an OrderLineItem and establish control over the attributes of the Product on which it depends?