Search code examples
ruby-on-railsrubyrspecresque

How to test actions with queue workers?


I have an action create in UsersController which looks like this

def create
  @user = User.new(params[:user])
  if @user.save
    sign_in_as(@user)
    Resque.enqueue(MailWorker, @user.email)
    redirect_to root_url, notice: "Thanks"
  else
    render "new"
  end
end

Before I added reqsue to this action, I've been testing email confrimation like this

it "creates a new user account" do
  # code for creating a new account...

  ActionMailer::Base.deliveries.size.should == 1
  mail = ActionMailer::Base.deliveries.last
  mail.to.should == [user[:email]]
  mail.body.encoded.should match(/Thank you for registration/)
end

But now, since I added resque worker to deliver the message, I guess it doesn't deliver the message instantly and therefore I'm getting this test failed with the message

 Failure/Error: ActionMailer::Base.deliveries.size.should == 1
   expected: 1
        got: 0 (using ==)

How can I test such cases, when async workers are involved and the result depends on them?


Solution

  • Now that you've decoupled the mail delivery from your controller, you will also be able to decouple the tests. What I've done in the past for this is use the resque_spec Gem which lets you add assertions for whether or not the jobs have been enqueued as expected.

    You will be adding something like this in your tests:

    MailWorker.should have_queued(user.email)