1

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

提现.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 测试这些示波器吗?

4

2 回答 2

2

大致猜测您的模式,您首先必须为所有部分及其关联设置工厂。这是一个粗略的轮廓。您必须使用有效值填写它们的其他属性。

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

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

测试排序范围很容易。制作一系列不同金额的提款,按照您的预期对它们进行排序,然后看看您是否可以取回。

我们的工厂已经设置好给我们随机的total_paid_amounts 兑现。我们只需要创建它们的列表。

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)
  }

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

  context 'when the partner is an administrator' do
    before {
      partner.update!(partner_type: 'administrator')
    }

    it '...'    
  end

依此类推。

于 2020-02-15T21:56:21.053 回答
0

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

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

Cashout.sort_by_total_paid_amount_asc.to_sql.should == \ 
Cashout.order('total_paid_amount ASC').to_sql
于 2013-04-16T22:45:52.350 回答