I am trying to understand in what format :at
for ActiveJob
is, so I can use assert_enqueued_with
with :at
parameter.
Currently I've got this test which passes:
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
But then I've realised that assert_enqueued_with
has :at
parameter and I would prefer to use it instead of last two lines in the block. Problem is, tomorrow
variable seems to be in a different format than :at
, which makes this fail:
tomorrow = 1.day.from_now.to_date
assert_enqueued_with(job: ActionMailer::DeliveryJob, at: tomorrow) do
onboarding.start_onboarding
end
with this error:
Minitest::Assertion: No enqueued job found with {:job=>ActionMailer::DeliveryJob, :at=>Wed, 31 May 2017 13:12:05 UTC +00:00}
As you can see, tomorrow
is a date, say Wed, 31 May 2017
, while job_date
is some kind of a large number, say 1496236366.183789
. Hence I am trying to convert tomorrow
into the same format.
Would really appreciate some help with this. Perhaps I am using :at
wrongly or you know what format :at
in and help me convert tomorrow
.
start_onboarding
is just a AASM event, which calls this method to schedule email delivery (a bit modified for privacy reasons):
def notify(id)
person = User.find(id)
PersonMailer.onboarding_reminder(person).
deliver_later(wait_until: 1.day.from_now)
end
The argument for the wait_until
method needs to match what your test uses. The date serialized into the queue does get turned into a float by rails. And in your #notify
method, you're passing in a ActiveSupport::TimeWithZone
instance when your test is passing in a Date
instance.
See here:
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
That means your job is getting enqueued with time information but your test is expecting a simple date. I'm not sure which is more correct the test date or the code date but they need to match for this test to pass.
Per the comments, here's how you might use Timecop
to help you out:
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