![](/img/trans.png)
[英]RSPEC fails controller test (transaction) but works in the browser (rails 4)
[英]Rails Rspec test fails when it works in app
我有以下代碼並測試似乎無法通過。 該代碼應自動鎖定所有在24小時前完成的預訂。
當我撬入測試並運行Booking.auto_lock_guests的第一行時,什么都沒有發生。 當我輸入booking_7並在輸入Booking.auto_lock_guests之后,它將更改為true。 這與讓設置未在Booking.all中顯示的方式有關嗎? 還是我編寫測試的方式?
任何幫助將不勝感激。
def self.auto_lock_guests
bookings = Booking.where(guests_completed: true, locked: false)
bookings.each do |booking|
next unless booking.guests_completed_at <= 1.day.ago
booking.locked = true
booking.save
end
end
context 'auto_lock_guests' do
let(:booking_6) { FactoryGirl.create(:booking, date: Date.today - 5.day, guests_completed: true, guests_completed_at: DateTime.now, locked: false )}
let(:booking_7) { FactoryGirl.create(:booking, date: Date.today - 5.day, guests_completed: true, guests_completed_at: DateTime.now - 3.day, locked: false )}
before do
Booking.auto_lock_guests
end
it 'should only lock bookings with a guests_completed date older than a day ago' do
expect(booking_7.locked).to eq(true)
expect(booking_6.locked).to eq(false)
end
end
let
被懶惰地評估。 執行before
塊時,沒有記錄,因為還沒有調用let
塊。
要么改變let
let!
立即執行區塊或在Booking.auto_lock_guests
之前Booking.auto_lock_guests
致電booking_6
和booking_7
編輯:
另外,您不檢查booking.save
是否成功。保存成功。 如果booking.save
失敗-您將永遠不會知道。 :)
next unless booking.guests_completed_at <= 1.day.ago
可以重寫為查詢: where(Booking.arel_table[:guests_completed_at].gt(1.day.ago))
您無需首先遍歷記錄。 實際上,這將在您的應用擴展時引起問題,因為將所有這些記錄拉入內存將耗盡服務器(或dynos)的內存。
您可以從數據庫中選擇記錄,並在單個查詢中更新它們:
class Booking
def self.auto_lock_guests!
bookings = Booking.where(guests_completed: true, locked: false)
.where('guests_completed_at <= ?', 1.day.ago)
bookings.update_all(locked: true)
end
end
許多單獨的UPDATE查詢與一次更新許多行之間的執行時間差異可能很大。
要測試它,您可以創建多個記錄並使用更改期望:
# use describe and not context for methods.
describe ".auto_lock_guests" do
# let! is not lazy loading
let!(:old_booking) { FactoryGirl.create(:booking, date: 7.days.ago, guests_completed: true, guests_completed_at: 3.days.ago, locked: false )}
let!(:new_booking) { FactoryGirl.create(:booking, date: Date.today, guests_completed: true, guests_completed_at: DateTime.now, locked: false )}
it 'locks a booking with a guests_completed date older than a day ago' do
expect do
Bookings.auto_lock_guests! && old_booking.reload
end.to change { old_booking.locked }.from(false).to(true)
end
it 'does not lock a when guests_completed date is less than a day ago' do
expect do
Bookings.auto_lock_guests! && new_booking.reload
end.to_not change { new_booking.locked }.from(false).to(true)
end
end
在測試更改數據庫的方法時,使用change
是一個好主意,因為這些方法可以驗證初始狀態和結果。
我最終不得不在調用Booking.auto_lock_guests之后將其添加到before操作中,並且可以正常工作。
before do
Booking.auto_lock_guests
booking_7.reload
booking_6.reload
end
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.