Reputation: 2105
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
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