与RSpec的has_many关系中的测试顺序

时间:2015-05-15 12:35:17

标签: ruby-on-rails ruby rspec

我对Rails和RSpec不是很有经验,并且经常在编写测试时遇到麻烦。所以,我的下一个麻烦是我不知道如何正确测试模型关系中的顺序。

假设我有这样简单的模型:

class Kitchen < ActiveRecord::Base
  has_many :orders, -> { order(completed_at: :desc) }
end

对该模型的简单测试:

require 'rails_helper'

RSpec.describe Kitchen, :type => :model do
  before { @kitchen = FactoryGirl.create(:kitchen) }

  subject { @kitchen }

  describe "orders" do
    before do
      @kitchen.orders.build(description: "Test description 1",
        completed_at: 1.day.ago.localtime)

      @kitchen.orders.build(description: "Test description 2",
        completed_at: Time.now)
    end

    it "should be sorted by completion date in descending order" do
      expect(@kitchen.orders.first.completed_at).to be > @kitchen.orders.last.completed_at
    end
  end
end

结果我收到了错误:

Failure/Error: expect(@kitchen.orders.first.completed_at).to be > @kitchen.orders.last.completed_at
   expected: > Fri, 15 May 2015 12:21:54 UTC +00:00
        got:   Thu, 14 May 2015 12:21:54 UTC +00:00

任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:2)

您正在使用build。这不会持久存储到数据库中,因此当您调用@kitchen.orders.first时,您没有访问数据库,只是返回您创建的第一个数据库,这是错误的数据库。

改为使用create,然后调用@kitchen.reload从数据库中刷新。

答案 1 :(得分:2)

以下内容如何:

it {
    is_expected.to have_many(:orders).order( completed_at: :desc )
}

答案 2 :(得分:1)

我会做这样的事情:

RSpec.describe Kitchen, :type => :model do
  let(:kitchen) { FactoryGirl.create(:kitchen) }

  describe 'orders' do
    let(:yesterday) { 1.day.ago }
    let(:today)     { Time.now }

    before do
      # `create` actually saves the objects into the database
      kitchen.orders.create(description: '1', completed_at: today)
      kitchen.orders.create(description: '2', completed_at: yesterday)
    end

    # `(true)` forces a reload of the associated objects
    subject(:orders) { kitchen.orders(true) } 

    it 'should be sorted by completion date in descending order' do
      expect(orders.map(&:completed_at)).to eq [yesterday, today]
    end
  end
end