While I have used Sidekiq for years now, I’m also a big fan of ActiveJob. I still use vanilla Sidekiq workers for some tasks, where I require many of the advanced features of Sidekiq that aren’t available in ActiveJob, but ActiveJob workers are just great for a vast majority of tasks.
In this post, we’ll take a quick look at how you can test ActiveJob callbacks and error handling in your jobs.Our Worker
Let’s first define a simple worker that raises an exception, that we expect to handle by logging with the Rails logger.
This isn’t a very exciting worker, but it does show that when performed we will immediately raise a simple exception, which we expect to be handled gracefully by logging to the console.
First Attempt at Testing
I would normally test this out by mocking the API communication layer in a unit test, so my spec would look like the following:
While this looks perfectly reasonable, and we’re testing the “perform” method of our worker just fine, this test will actually fail. It has to do with how ActiveJob is performing our worker.
Looking through the documentation and source for “perform” vs “perform_now”, it’s apparent that “perform_now” is actually required to run callbacks and handle errors. So we need to update our test to reflect that:
subject.perform => subject.perform_now
With that change, our test will pass!
Simplest Test Case
While that change does get the test passing, we can refactor our test to be even simpler to relay what is being tested here.
I’ve now removed any necessary knowledge of using the API client itself, and just asserted that if the “perform” method raises this error, presumably b/c we’ve called the API client and it was not handled there, that all is well.
If you need help running Sidekiq (with or without Rails) on startup, take a look at our post "How to Manage Ruby Processes at Launch".