如何构建我的RSpec测试文件夹,文件和数据库?

时间:2015-08-10 13:46:18

标签: ruby-on-rails ruby rspec rspec-rails functional-testing

我已经在RoR开发了一年多了,但我刚刚开始使用RSpec进行测试。

对于标准模型/控制器测试,我通常没有任何问题,但问题是我想测试一些复杂的功能过程,并且不知道如何构建我的测试文件夹/文件/数据库。

这是我的应用程序的基本结构:

class Customer
  has_one    :wallet
  has_many :orders    
  has_many :invoices, through: :orders
  has_many :invoice_summaries
end

class Wallet
  belongs_to :customer
end

class Order
  has_one    :invoice
  belongs_to :customer
end

class Invoice
  belongs_to :order
  belongs_to :invoice_summary
end

class InvoiceSummary
  belongs_to :customer
  has_many  :invoices
end

主要问题是我想模拟对象的生命周期,意思是:

  • 实例化将用于所有测试的客户和钱包(无需重新初始化)

  • 模拟时间流程,创建和更新多个订单/发票对象以及一些invoice_summaries。

为了创建和更新订单/发票/ invoice_summaries,我想有像

这样的方法
def create_order_1
  # code specific to create my first order, return the created order
end

def create_order_2
  # code specific to create my second order, return the created order
end
.
.
.
def create_order_n
  # code specific to create my n-th order, return the created order
end

def bill_order(order_to_bill)
  # generic code to do the billing of the order passed as parameter
end

def cancel_order(order_to_cancel)
  # generic code to cancel the order passed as parameter
end

我已经找到了用于模拟时间流的gem Timecop。因此,我希望有一个易于理解的最终测试,看起来像

# Code for the initialization of customers and wallets object

describe "Wallet should be equal to 0 after first day" do
  Timecop.freeze(Time.new(2015,7,1))
  first_request = create_request_1
  first_request.customer.wallet.value.should? == 0
end

describe "Wallet should be equal to -30 after second day" do
  Timecop.freeze(Time.new(2015,7,2))
  bill_order(first_request)
  second_order = create_order_2
  first_request.customer.wallet.value.should? == -30
end

describe "Wallet should be equal to -20 after third day" do 
  Timecop.freeze(Time.new(2015,7,3))
  bill_order(second_request)
  cancel_order(first_request)
  first_request.customer.wallet.value.should? == -20
end

describe "Three first day invoice_summary should have 3 invoices" do
  Timecop.freeze(Time.new(2015,7,4))
  invoice_summary = InvoiceSummary.create(
      begin_date: Date.new(2015,7,1),
      end_date: Date.new(2015, 7,3)
  ) # real InvoiceSummary method
  invoice_summary.invoices.count.should? == 3
end

有没有人有这样的测试?是否有构建对象工厂,编写测试等的良好实践?

例如,我被告知有一个好主意是将客户/电子钱包创建放在db / seed.rb文件中,但之后我真的不知道如何处理它。

1 个答案:

答案 0 :(得分:0)

您应该使用FactoryGirl完成任务。按照文档中的描述进行配置,然后像这样使用它:

# factories.rb
factory :order do
end

# your spec
first_order = create(:order, ...) # configure parameters of order in-place

或者让特定工厂处理不同类型的请求:

# factories.rb
factory :expensive_order, class: Order do
  amount 999 # have 'amount' field of Order be equal to 999
end

# your spec
first_order = create(:expensive_order)

您可以让FactoryGirl自动处理您的关联:

factory :order do
  association :user # automatically create User association
end

您正在描述FactoryGirl的开发人员打算解决的确切问题。