代码之家  ›  专栏  ›  技术社区  ›  Georgeheap

Rails Rspec测试在应用程序中运行时失败

  •  0
  • Georgeheap  · 技术社区  · 8 年前

    我有以下代码和测试,我似乎无法通过。代码应该自动锁定24小时前完成的所有预订。

    当我开始测试并运行第一行预订时。auto\u lock\u客人什么都没发生。当我键入booking_7,然后键入booking。auto\u lock\u guests然后将其更改为true。这与let的设置方式有关吗?它没有出现在预订中。全部的还是我写测试的方式?

    任何帮助都将不胜感激。

      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
    
    3 回复  |  直到 8 年前
        1
  •  1
  •   Magnuss    8 年前

    let 延迟评估。当 before 块执行时没有记录,因为 允许 尚未调用块。

    要么改变 允许 let! 立即执行块或调用 booking_6 booking_7 Booking.auto_lock_guests

    编辑:

    你也不用检查 booking.save 成功。如果 预订拯救 失败-你永远不会知道。:)

    这个 next unless booking.guests_completed_at <= 1.day.ago 可以重写为查询: where(Booking.arel_table[:guests_completed_at].gt(1.day.ago))

        2
  •  1
  •   max Mike Williams    8 年前

    首先,您不需要遍历记录。事实上,随着应用程序的扩展,它会导致问题,因为将所有这些记录拉入内存将耗尽服务器(或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
    

    要测试它,您可以创建多个记录并使用更改预期:

    # 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 在测试在验证初始状态和结果时更改数据库的方法时,这是一个非常好的主意。

        3
  •  0
  •   Georgeheap    8 年前

    在打电话预订后,我最后不得不将此添加到before action中。auto_lock_客人,它成功了。

    before do
      Booking.auto_lock_guests
      booking_7.reload
      booking_6.reload
    end