[英]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.