ActiveJob :at key 是什么格式

In what format is ActiveJob :at key

我想了解 ActiveJob:at 是什么格式,所以我可以将 assert_enqueued_with:at 参数一起使用。

目前我已经通过了这个测试:

tomorrow = 1.day.from_now.to_date
assert_enqueued_with(job: ActionMailer::DeliveryJob) do
  onboarding.start_onboarding
  job_date = ActiveJob::Base.queue_adapter.enqueued_jobs[0][:at]
  assert_equal tomorrow, Time.at(job_date).to_date
end

但后来我意识到 assert_enqueued_with:at 参数,我更愿意使用它而不是块中的最后两行。问题是,tomorrow 变量的格式似乎与 :at 不同,这导致失败:

tomorrow = 1.day.from_now.to_date
assert_enqueued_with(job: ActionMailer::DeliveryJob, at: tomorrow) do
  onboarding.start_onboarding
end

出现此错误:

Minitest::Assertion: No enqueued job found with {:job=>ActionMailer::DeliveryJob, :at=>Wed, 31 May 2017 13:12:05 UTC +00:00}

如您所见,tomorrow 是一个日期,比如 Wed, 31 May 2017,而 job_date 是一个大数字,比如 1496236366.183789。因此,我试图将 tomorrow 转换为相同的格式。

非常感谢对此的一些帮助。也许我用错了 :at 或者你知道 :at 的格式并帮助我转换 tomorrow.

start_onboarding 只是一个 AASM 事件,它调用此方法来安排电子邮件发送(出于隐私原因进行了一些修改):

def notify(id)
  person = User.find(id) 
  PersonMailer.onboarding_reminder(person).
    deliver_later(wait_until: 1.day.from_now)
end

wait_until 方法的参数需要与您的测试使用的相匹配。序列化到队列中的日期确实被 rails 变成了浮点数。在您的 #notify 方法中,当您的测试传递 Date 实例时,您传递的是 ActiveSupport::TimeWithZone 实例。

看这里:

1.day.from_now
=> Wed, 31 May 2017 13:56:36 UTC +00:00
1.day.from_now.class
=> ActiveSupport::TimeWithZone
1.day.from_now.to_date
=> Wed, 31 May 2017
1.day.from_now.to_date.class
=> Date
1.day.from_now == 1.day.from_now.to_date
=> false

这意味着您的作业正在排队等待时间信息,但您的测试需要一个简单的日期。我不确定测试日期或代码日期哪个更正确,但他们需要匹配才能通过此测试。

根据评论,以下是您可以如何使用 Timecop 来帮助您:

  tomorrow = 1.day.from_now.to_date
  Timecop.freeze(tomorrow)
  assert_enqueued_with(job: ActionMailer::DeliveryJob, at: tomorrow) do
    onboarding.start_onboarding
  end
  Timecop.return

at 选项应该是时间。

查看文档中的示例 here