我对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
任何帮助将不胜感激。
答案 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