bakedweb logo

Design and Web Development from Downtown Miami.

Testing sending a delayed_job email with Cucumber

with 9 comments

I recently implemented delayed_job into one of our applications. It was done because the application was dropping emails at the expense of user experience. We had about 120+ “Net::SMTPServerBusy” notifications and something had to be done about that.

We had about six places in our application where the email-spec gem came into play with a nicely:

Then “thebaker@bakedweb.net” should receive 1 ?email

After implementing delayed_job they changed to:

Then “thebaker@bakedweb.net” should receive 1 delayed email

The question is: How would I go about implementing the step? I came up with the following:

Then /^"([^\"]*)” should receive 1 delayed email$/ do |arg1|
Delayed::Job.last.name[0..15].should == ‘Notifier.deliver’
end

I know my implementation is dirty and brakes if we are sending the email from somewhere else, but Notifier and it only takes into account 1 email. The real reason for this post is to pick you mind on how to better implement the step. How would you go about it?

Update: Kotrin from #cucumber came up with a neat regex for the step and tells us that we could probably expand on it to pick up on args.


Then /^"([^\"]*)” should receive 1 delayed email$/ do |arg1|
Delayed::Job.last.name.should match(/^Notifier\.deliver/)
end

Written by ivan

August 5th, 2009 at 8:18 am

Posted in ruby on rails

Tagged with , , ,

9 Responses to 'Testing sending a delayed_job email with Cucumber'

Subscribe to comments with RSS or TrackBack to 'Testing sending a delayed_job email with Cucumber'.

  1. Thanks, I use your idea and it works fine!

    RuthFel

    13 Oct 09 at 3:00 am

  2. Before using delayed job I used cucumber/pickle to test the delivery of the emails. After DelayedJob I use direct AR checking for last job as you showed in you post.

    But still I have to make another set of cucumber tests to check if delayed_job is actually doing its job and deliver the email correctly, and test the content of the emails.

    ibrahim ahmed

    20 Oct 09 at 11:38 am

  3. It may be useful to add that after making sure that the delayed job was fired successfully as you explained, we can run (may be at the same scenraio) something like..

    Given last delayed job was finished
    Then 1 email should be delivered to contact@email.com

    In which we run the last job using the following code…

    Given /^last delayed job was finished$/ do
    Delayed::Job.reserve_and_run_one_job
    end

    Then we could test our emails delivery as usual. I prefer using Pickle it includes very useful email step definitions like shown in the given scenario.

    You can get Pickle from this url:
    http://github.com/ianwhite/pickle

    ibrahim ahmed

    20 Oct 09 at 12:19 pm

  4. Ibrahim - I totally agree with you. So far, I assumed DelajedJob was doing its job, but a extra set of test to guarantee it.

    Do you think it is worth it to add this to pickle or email_spec?

    ivan

    20 Oct 09 at 3:19 pm

  5. nice info. I’m sure this is useful for uploads and other stuff.
    did you use delayed_job on MediaTemple?

    Psousa

    19 Nov 09 at 12:18 pm

  6. @psousa Yes I did. We are moving to Heroku witch makes it super easy to work with delayed_job.

    admin

    27 Nov 09 at 12:30 pm

  7. Thank you so much for this. I was having a hard time trying to figure out how to test delayed jobs.

    calebhc

    1 Feb 10 at 4:10 pm

  8. Following up on Ibrahim’s suggestion, we actually added the following step:

    Given /^all delayed jobs have finished$/ do
    Delayed::Job.work_off
    end

    That allowed us to run the following test:

    Given all last delayed jobs have finished
    Then 1 email should be delivered to contact@email.com

    We’re enqueuing our jobs in a .each block, and one action on our site can sometimes trigger multiple emails.

    tildeequals

    19 Apr 10 at 4:40 pm

  9. niiice one peeps.

    James Callaway

    3 Jun 10 at 1:08 pm

Leave a Reply