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
我想了解 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