7

I am processing my background jobs using Resque. My model looks like this

class SomeClass
  ...
  repo = Repo.find(params[:repo_id])
  Resque.enqueue(ReopCleaner, repo.id)
  ...
end

class RepoCleaner
  @queue = :repo_cleaner

  def self.perform(repo_id)
    puts "this must get printed in console"
    repo = Repo.find(repo_id)    
    # some more action here
  end
end

Now to test in synchronously i have added

Resque.inline = Rails.env.test?

in my config/initializers/resque.rb file

This was supposed to call #perform method inline without queuing it into Redis and without any Resque callbacks as Rails.env.test? returns true in test environment.

But

"this must get printed in console"

is never printed while testing. and my tests are also failing.

Is there any configurations that i have missed. Currently i am using

resque (1.17.1)
resque_spec (0.7.0)
resque_unit (0.4.0)
Nakilon
  • 34,866
  • 14
  • 107
  • 142
Gagan
  • 4,278
  • 7
  • 46
  • 71

3 Answers3

8

I personally test my workers different. I use RSpec and for example in my user model I test something like this:

it "enqueue FooWorker#create_user" do
  mock(Resque).enqueue(FooWorker, :create_user, user.id)
  user.create_on_foo
end

Then I have a file called spec/workers/foo_worker_spec.rb with following content:

require 'spec_helper'

describe FooWorker do

  describe "#perform" do
    it "redirects to passed action" do
      ...
      FooWorker.perform
      ...
    end
  end

end

Then your model/controller tests run faster and you don't have the dependency between model/controller and your worker in your tests. You also don't have to mock so much things in specs which don't have to do with the worker.

But if you wan't to do it like you mentioned, it worked for me some times ago. I put Resque.inline = true into my test environment config.

  • Thanks for a different approach, but my concern is, even though i put Resque.inline = true in my initializer/resque.rb file its not working not as expected. ie the puts statement is not executed. – Gagan Aug 28 '11 at 02:07
  • But is it only the put which won't work? Try to execute something like `echo bla > /tmp/test` – Daniel Spangenberg Aug 28 '11 at 02:47
  • I think both approaches are valid. If you want end-to-end specs, then `Resque.inline = true` works. If you are writing model specs, then it is not necessary. – B Seven Jun 04 '14 at 19:27
0

It looks like the question about logging never got answered. I ran into something similar to this and it was from not setting up the Resque logger. You can do something as simple as:

Resque.logger = Rails.logger

Or you can setup a separate log file by adding this to your /lib/tasks/resque.rake. When you run your worker it will write to /log/resque.log

Resque.before_fork = Proc.new {
ActiveRecord::Base.establish_connection

# Open the new separate log file
logfile = File.open(File.join(Rails.root, 'log', 'resque.log'), 'a')

# Activate file synchronization
logfile.sync = true

# Create a new buffered logger
Resque.logger = ActiveSupport::Logger.new(logfile)
Resque.logger.level = Logger::INFO
Resque.logger.info "Resque Logger Initialized!"
}

Mocking like daniel-spangenberg mentioned above ought to write to STDOUT unless your methods are in the "private" section of your class. That's tripped me up a couple times when writing rspec tests. ActionMailer requires it's own log setup too. I guess I've been expecting more convention than configuration. :)

CappuccinoRob
  • 141
  • 2
  • 3
0

In the spec_helper.rb

you can add

config.before :each do
    Resque.inline = true
end

I was facing same issue, with above it solved it.

jbmyid
  • 1,985
  • 19
  • 22