如何用rspec测试范围

时间:2013-04-16 21:47:35

标签: ruby-on-rails rspec scope

这些是我的Cashout模型的一些代码。我可以使用rspec测试所有模型,但我不知道如何测试这些范围。

cashout.rb

class Cashout < ActiveRecord::Base

belongs_to :partner

scope :add_virtual_columns, select(
    "cashouts.*,
    ( SELECT SUM(c.amount) FROM cashouts c WHERE c.partner_id = cashouts.partner_id) as total_paid_amount,
    (
      (
      CASE
        WHEN (SELECT partner_type FROM partners WHERE cashouts.partner_id = partners.id) = 'administrator'
        THEN
          (
            CASE 
                WHEN ( SELECT SUM(cr.partner_profit) FROM contact_records cr WHERE cr.partner_id in (SELECT id FROM partners WHERE company_id in (SELECT company_id FROM partners WHERE id = cashouts.partner_id))) IS NULL
                THEN 0 
                ELSE ( SELECT SUM(cr.partner_profit + cr.company_profit) FROM contact_records cr WHERE cr.partner_id in (SELECT id FROM partners WHERE company_id in (SELECT company_id FROM partners WHERE id = cashouts.partner_id)))
            END
            )
        ELSE
          (
          CASE 
            WHEN ( SELECT SUM(cr.partner_profit) FROM contact_records cr WHERE cr.partner_id = cashouts.partner_id) IS NULL
            THEN 0 
            ELSE ( SELECT SUM(cr.partner_profit) FROM contact_records cr WHERE cr.partner_id = cashouts.partner_id)
          END
          )
      END
      )
      -
      ( SELECT SUM(c.amount) FROM cashouts c WHERE c.partner_id = cashouts.partner_id)
    ) as unpaid_amount"
  ).group('cashouts.id')
  scope :sort_by_total_paid_amount_asc, order("total_paid_amount ASC")
  scope :sort_by_total_paid_amount_desc, order("total_paid_amount DESC")
  scope :sort_by_unpaid_amount_asc, order("unpaid_amount ASC")
  scope :sort_by_unpaid_amount_desc, order("unpaid_amount DESC")
end

您知道如何使用rspec和factorygirl测试这些范围吗?

2 个答案:

答案 0 :(得分:1)

大致根据您的模式进行猜测,首先必须为所有零件及其关联建立工厂。这是一个粗略的轮廓。您必须使用有效值填写其他属性。

Faker对于填写有效数据非常有用。

if ( has_term( 'udstillingsmodel', 'product_tag' ) ) {

}

测试排序范围很容易。制作一系列不同金额的现金支出,按预期进行排序,然后查看是否可以收回。

我们的工厂已经设置好,可以为我们提供随机的total_paid_amounts现金取款。我们只需要创建一个列表即可。

factory :company do
end

factory :partner do
  company
end

factory :contact_record do
  partner
end

factory :cashout do
  partner
  total_paid_amount { Faker::Number.digit }
end

我避免按顺序生成套现。这样可以将它们按顺序放在表中,并且其默认排序可能符合我们的期望。

尽管我对这样的字面意义和琐碎的作用域的价值表示怀疑。它们很容易写为context 'with cashouts' do let(:cashouts) { create_list(:cashout, 3) } describe '.sort_by_total_paid_amount_asc' do it 'sorts by total_paid_amount in ascending order' do expect( Cashout.sort_by_total_paid_amount_asc.to_a ).to eq cashouts.sort_by(&:total_amount_paid) end end describe '.sort_by_total_paid_amount_desc' do it 'sorts by total_paid_amount in descending order' do expect( Cashout.sort_by_total_paid_amount_desc.to_a ).to eq cashouts.sort_by(&:total_amount_paid).reverse end end end ,不需要测试。


测试Cashout.order(total_paid_amount: :asc) ... add_virtual_columns是一个不好的名字。似乎正在添加单个列add_virtual_columns。我称它为unpaid_amount

with_unpaid_amount更复杂,因为它非常复杂并且需要更多测试数据。幸运的是,我们在工厂建立了关系。

首先,我们设置对象,以便它们都共享同一伙伴。有几种方法可以做到这一点,但我选择了生成合作伙伴并将其传递。这样可以更轻松地修改每个对象以测试不同的场景。

with_unpaid_amount

现在,您可以更改对象以测试不同的场景。例如,如果合作伙伴是管理员怎么办?

describe '.with_unpaid_amount' do
  let(:partner) {
    create(:partner)
  }
  let(:company) {
    create(:company, partner: partner)
  }
  let(:cashout) {
    create(:cashout, partner: partner)
  }
  let(:contact_record) {
    create(:contact_record, partner: partner)
  }

依此类推。

答案 1 :(得分:0)

我倾向于创建一些测试数据并将范围结果与您期望的结果进行比较。 FactoryGirl可以帮助您创建基础Cashout模型,您可以在其上覆盖amountpartner_id,然后生成相应的PartnerContactRecord模型。< / p>

对于后一个范围,您可以执行类似

的操作
Cashout.sort_by_total_paid_amount_asc.to_sql.should == Cashout.order('total_paid_amount ASC').to_sql