Happy New Year everyone.
In my Rails app I have invoices
which can have many nested items
:
class Invoice < ActiveRecord::Base
belongs_to :user
has_many :items
accepts_nested_attributes_for :items, :reject_if => :all_blank, :allow_destroy => true
...
end
The controller looks like this:
class InvoicesController < ApplicationController
before_action :find_invoice
...
def new
@invoice = current_user.invoices.build(:number => current_user.next_invoice_number)
@invoice.build_item(current_user)
end
def create
@invoice = current_user.invoices.build(invoice_params)
if @invoice.save
flash[:success] = "Invoice created."
redirect_to edit_invoice_path(@invoice)
else
render :new
end
end
...
private
def find_invoice
@invoice = Invoice.find(params[:id])
end
end
In order to be able to create RSpec tests for this I started off by defining a factory:
FactoryGirl.define do
factory :invoice do
number { Random.new.rand(1..1000000) }
end
factory :item do
date { Time.now.to_date }
description "Just a test"
price 50
quantity 2
tax_rate 10
end
end
What is the best way to tell RSpec that it should always include 2 items
with any invoice
that gets created during a test?
I find this difficult because RSpec doesn't care about my new
controller action.
What is the Rails way to do this?
Thanks for any help.
You could use calbacks feature of factory_girl. Here is an article on that: http://robots.thoughtbot.com/get-your-callbacks-on-with-factory-girl-3-3
In this case following line, added to the invoice factory will probably do the job:
after(:create) {|instance| create_list(:item, 2, invoice: instance) }
And it should be used by Rspec like this:
describe InvoicesController do
describe "#new" do
before do
create(:invoice)
end
# expectations here
end
end