Yeggeps
Yeggeps

Reputation: 2105

Integration testing or mocking with Resque enqueuing?

How would you test this class? Would you integrate it with Resque and check that the job gets put in the queue or would you mock it, and if you would mock it how would you avoid just duplicating the code like shown in example spec.

class BookingReminderEnqueuer
  def initialize(user, booking, worker = BookingReminder)
    @user, @booking, @worker = user, booking, worker
  end

  def enqueue
    Resque.enqueue_at(
      remind_user_at,
      @worker,
      booking_id: @booking.id,
      user_id: @user.id
    ) if @booking.remind_user?
  end

  private
  def remind_user_at
    @booking.start_time - 6.hours
  end
end

require 'spec_helper'
describe BookingReminderEnqueuer
  describe "#enqueue" do
    context "when the user should have a reminder" do
      it "enqueues the reminder" do
        booking.stub(:remind_user?) { true }
        Resque.should_receive(:enqueue_at).with(
          booking.start_time - 6.hours,
          BookingReminder,
          booking_id: booking.id,
          user_id: user.id
        ).once
        booking_reminder_enqueuer.enqueue
      end
    end

    context "when the user shouldn't have a reminder" do
      it "does not enqueue the reminder" do
        booking.stub(:remind_user?) { false }
        Resque.should_not_receive(:enqueue_at)
      end
    end
  end
end

Upvotes: 2

Views: 1844

Answers (1)

Winfield
Winfield

Reputation: 19145

I would use a gem like fakeredis to create a test redis db. This will create an isolated in-memory Redis instance for testing that can be cleared around test runs. Then you can verify that the job is enqueued properly with the right parameters vs. mocking the enqueue method (since getting the enqueue parameters to work properly is the heart of this method.

    # Gemfile
    group :test do
      gem "rspec"
      gem "fakeredis", :require => "fakeredis/rspec"
    end


    # Spec
    describe BookingReminderEnqueuer
      describe "#enqueue" do
        context "when the user should have a reminder" do
          it "enqueues the reminder" do
            booking.stub(:remind_user?) { true }
            booking_reminder_enqueuer.enqueue
            resque_job = Resque.peek(:queue_name)
            resque_job.should be_present
            # add assertions about job content/scheduling here
          end
        end
        ...
     end
   end

Upvotes: 5

Related Questions