Rails测试依赖于时间,使用Timecop的问题

时间:2014-11-06 14:08:01

标签: ruby-on-rails ruby time rspec

我有一个模型可以删除超过两天未更新的所有记录。我正在使用AR回调来触发相关方法。

  CHECK_INTERVAL = 1.days
  RECORDS_GREATER_THAN = 2.days

  before_create :clear_old_records
  scope :unused_shopping_baskets, -> { where("updated_at < ? AND workflow_state=?", Time.zone.now - RECORDS_GREATER_THAN, 'basket') }

  def clear_old_records
    if ShoppingBasket.time_to_check?
      records = ShoppingBasket.unused_shopping_baskets
      if records
        records.destroy_all
      end
    end
  end

  def self.time_to_check?
    basket=self.first
    basket.present? ? basket.created_at<(Time.now-CHECK_INTERVAL) : true
  end

我在rails控制台中玩过这个,所以我很有信心它的工作原理。但是我希望通过使用测试可以肯定地说,但是处理时间可能会令人头疼,这就是我想使用Timecop的原因。

  let(:shopping_basket_1){FactoryGirl.create :shopping_basket}
        describe "deleting old baskets" do
    before do 
      shopping_basket_1
    end

    context "day one" do 

      it "records still exist" do 
        expect(ShoppingBasket.all.count).to eq 1
      end

      it "is time to check" do 
        expect(ShoppingBasket.time_to_check?).to be_falsey
      end
    end


    context "1 day in the future" do 
      before do 
        Timecop.travel(Time.zone.now + 24.hours) 
      end 

      it "is time to check" do 
        expect(ShoppingBasket.time_to_check?).to be_truthy
      end

      it "records still exist" do 
        expect(ShoppingBasket.all.count).to eq 1
      end

    end

    context "2 days in the future" do 
      before do 
        Timecop.travel(Time.zone.now + 48.hours)
      end 

      it "scope includes shopping_basket_1" do 
        expect(ShoppingBasket.unused_shopping_baskets).to include shopping_basket_1

      end

      it "is time to check" do 
        expect(ShoppingBasket.time_to_check?).to be_truthy
      end

      it "shopping_basket_1 no longer exist" do 
        expect(ShoppingBasket.all.count).to eq 0
      end
    end
  end

然而,最后一个背景失败了。数据库中仍有1个项目。此外,当我在最后一个上下文中检查范围时,它显示为空,当我希望它包含shopping_basket_1

  1) ShoppingBasket deleting old baskets 2 days in the future scope includes shopping_basket_1
     Failure/Error: expect(ShoppingBasket.unused_shopping_baskets).to include shopping_basket_1
       expected #<ActiveRecord::Relation []> to include #<ShoppingBasket id: 3614, created_at: "2014-11-08 14:06:17", updated_at: "2014-11-08 14:06:17", simple_contact_with_address_id: 3502, sagepay_security_key: nil, workflow_state: "basket", frozen_value: nil>
       Diff:
       @@ -1,2 +1,2 @@
       -[#<ShoppingBasket id: 3614, created_at: "2014-11-08 14:06:17", updated_at: "2014-11-08 14:06:17", simple_contact_with_address_id: 3502, sagepay_security_key: nil, workflow_state: "basket", frozen_value: nil>]
       +[] 

  2) ShoppingBasket deleting old baskets 2 days in the future shopping_basket_1 no longer exist
     Failure/Error: expect(ShoppingBasket.all.count).to eq 0

       expected: 0
            got: 1

       (compared using ==)

示例是通过工厂女孩生成的

FactoryGirl.define do
  factory :shopping_basket do
    simple_contact_with_address
    workflow_state "basket"
  end
end

我在这里缺少什么?是我的测试还是我的代码,还是两者兼而有之??

谢谢,

0 个答案:

没有答案