Ruby rspec 中关于 timecop 的恒定日期变量

Ruby constant date variable with respect to timecop in rspec

您好,我有一个 Ruby class 和一些使用日期的常量变量:

START_DATE = Date.current.at_beginning_of_month.in_time_zone + 2.days

LAST_DATE = Date.current.at_beginning_of_month.in_time_zone + 10.days

我有一些方法在内部使用这个日期,如下所示:

Date.current.in_time_zone.between?(START_DATE, LAST_DATE)

在我的 rspec 文件中,我正在使用 Timecop.freeze 它破坏了我的测试。

是否有解决方法可以为我的大多数方法使用相同的变量?还是我用错了?

如有任何帮助,我将不胜感激!

无论您是否将 Timecop 用于测试中的其他交互,您可能还需要考虑对常量本身进行存根。一旦您测试了与设置常量相关的逻辑,请考虑使用 stub_const 来确保将常量设置为您希望在测试套件中使用的值。例如,您可能在测试套件中包含一个如下所示的块:

before :each do
  stub_const("MyClass::START_DATE", <start_time>)
  stub_const("MyClass::END_DATE", <end_time>)
end

已更新:

下面的评论说这不起作用,这很奇怪...绝对适合我。刚刚像这样测试过:

class User
  MY_CONST = "foo"

  def my_method
    MY_CONST
  end
end

然后在 rspec:

describe User do
  it "works unstubbed" do
    expect(User.new.my_const).to eq("foo")
  end
  it "works stubbed" do
    stub_const("User::MY_CONST", "bar")
    expect(User.new.my_const).to eq("bar")
  end
end

我实际上是从 Ruby slack 社区得到了这个答案 我得到了将其作为一种方法的建议。

类似:

def start_date
  Date.current.at_beginning_of_month.in_time_zone + 2.days
end

我也刚刚了解了@spickermann 的意思,为什么我不应该使用常量变量,因为它从服务器启动时就保持不变,它将具有初始值。从技术上讲,它不是一个常数。 :汗笑: