如何在RSpec测试中自动为发票创建嵌套项目?

时间:2014-01-01 20:01:16

标签: ruby-on-rails rspec factory-bot rspec-rails

大家新年快乐。

在我的Rails应用中,我有invoices,可以有许多嵌套items

class Invoice < ActiveRecord::Base

  belongs_to :user

  has_many :items

  accepts_nested_attributes_for :items, :reject_if => :all_blank, :allow_destroy => true

  ...

end

控制器如下所示:

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

为了能够为此创建RSpec测试,我首先定义了一个工厂:

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

告诉RSpec应该始终包含2 items并且任何 invoice在测试期间创建的最佳方法是什么?

我觉得这很难,因为RSpec不关心我的new控制器动作。

Rails 的方法是什么?

感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

你可以使用factory_girl的calbacks功能。这是一篇关于它的文章:http://robots.thoughtbot.com/get-your-callbacks-on-with-factory-girl-3-3

在这种情况下,在发票工厂中添加到发票工厂可能会完成这项工作:

after(:create) {|instance| create_list(:item, 2, invoice: instance) }

这应该被Rspec使用:

describe InvoicesController do

  describe "#new" do
    before do
      create(:invoice)
    end 

    # expectations here

  end

end