I'd like to verify that delayed_job callback hooks are getting called, but I don't see how to get RSpec to do it, especially when several layers of classes are involved.
Assuming I have an ActiveRecord model like this:
class MyJob < ActiveRecord::Base
def perform
# do some stuff
end
def after(job)
# called by delayed_job after perform completes
end
end
Conceptually, I want an RSpec test along these lines (though I know this isn't correct):
it 'should call the :after callback hook' do
my_job = MyJob.create
my_job.should_receive(:after).with(an_instance_of(Delayed::Backend::ActiveRecord::Job))
Delayed::Job.enqueue(my_job)
Delayed::Worker.new.work_off
end
I've pored over stackoverflow, relishapp.com/rspec and all the other places I can think of. It can't be too hard, right? (I bet @zetetic knows the answer in his sleep... ;)
(Caveat: My actual case uses a 'shim' class between MyJob and DJ. An answer for this simple case may trigger a more complex follow-on!)
IMHO i don't think this is the best thing to do...
By doing this, you're trying to spec DelayedJob's behavior, not your app, and DJ already has its own suit of tests.
Anyway, what about mocking DelayedJob itself? Maybe you can specify, by doing that, that your MockedJob will call your hook after processing, and you can create your matchers/expectations accordingly...
My suggestion would be to see if the Jobs table creates a new job record, and then introspect the details of that record. I've used something like this in the past.
it "should sync content from the remote CMS" do
DelayedJobs::CMS::Sync.module_eval do
def perform
url.should == "http://example.com/tools/datafeed/resorts/all"
Report.sync!([{'id' => 1, 'name' => 'resort foo'}])
end
end
lambda do
Report.sync_all!
end.should change(Delayed::Job, :count)
lambda do
Delayed::Job.work_off
end.should change(Resort, :count).by(2)
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With