| 1 |
=begin |
|---|
| 2 |
A mock of a BackgrounDRb instance running inside the 'test' environment. |
|---|
| 3 |
Instead of scheduling the task, then executing it asynchronously, we |
|---|
| 4 |
directly invoke the 'do_work' method of the Worker. |
|---|
| 5 |
|
|---|
| 6 |
This mock is needed because the actual BackgrounDRb instance, if running, is |
|---|
| 7 |
probably tied to a different environment than 'test'. Scheduled tasks that |
|---|
| 8 |
modify database entries will hit the instance's environment database (eg. |
|---|
| 9 |
'development' instead of the 'test' database), flunking tests in the best |
|---|
| 10 |
case and corrupting the instance's environment data in the worst case. |
|---|
| 11 |
|
|---|
| 12 |
To use, simply add the following line in your RAILS_ROOT/test_helper.rb: |
|---|
| 13 |
|
|---|
| 14 |
# inject the mock backgroundrb to the test environment. |
|---|
| 15 |
require File.dirname(__FILE__) + '/mocks/test/backgroundrb_mock.rb' |
|---|
| 16 |
=end |
|---|
| 17 |
|
|---|
| 18 |
module BackgrounDRb |
|---|
| 19 |
module Worker |
|---|
| 20 |
class RailsBase |
|---|
| 21 |
attr :results |
|---|
| 22 |
|
|---|
| 23 |
def initialize(workers) |
|---|
| 24 |
@results = {} |
|---|
| 25 |
@workers = workers |
|---|
| 26 |
end |
|---|
| 27 |
|
|---|
| 28 |
def logger |
|---|
| 29 |
ActiveRecord::Base.logger # pass through to the Rails logger |
|---|
| 30 |
end |
|---|
| 31 |
|
|---|
| 32 |
def delete |
|---|
| 33 |
@workers.delete self.object_id.to_s |
|---|
| 34 |
end |
|---|
| 35 |
|
|---|
| 36 |
def self.register ; end |
|---|
| 37 |
end |
|---|
| 38 |
end |
|---|
| 39 |
|
|---|
| 40 |
class MockDRbObject |
|---|
| 41 |
def initialize |
|---|
| 42 |
@workers = {} |
|---|
| 43 |
end |
|---|
| 44 |
|
|---|
| 45 |
def new_worker(opts={}) |
|---|
| 46 |
# instanciate the worker of appropriate class and pass args to do_work |
|---|
| 47 |
require "workers/#{opts[:class]}" |
|---|
| 48 |
worker_class = Inflector.constantize(Inflector.camelize(opts[:class].to_s)) |
|---|
| 49 |
worker = worker_class.new @workers |
|---|
| 50 |
worker_key = worker.object_id.to_s |
|---|
| 51 |
@workers[worker_key] = worker |
|---|
| 52 |
worker.do_work opts[:args] |
|---|
| 53 |
worker_key |
|---|
| 54 |
end |
|---|
| 55 |
|
|---|
| 56 |
def worker(key) |
|---|
| 57 |
# backgroundrb 0.2.1 raises NoMethodError when object is not found, |
|---|
| 58 |
# probably because when key is not found, nil is returned and not a |
|---|
| 59 |
# worker object, and calling nil.object fails later? |
|---|
| 60 |
nil.object unless @workers.has_key? key # raises NoMethodError |
|---|
| 61 |
@workers[key] |
|---|
| 62 |
end |
|---|
| 63 |
end |
|---|
| 64 |
|
|---|
| 65 |
class MiddleManRailsProxy |
|---|
| 66 |
def self.init |
|---|
| 67 |
MockDRbObject.new |
|---|
| 68 |
end |
|---|
| 69 |
end |
|---|
| 70 |
end |
|---|
| 71 |
|
|---|
| 72 |
# Overridde the MiddleMan from the backgroundrb plugin with our Mock. |
|---|
| 73 |
if Object.constants.include? 'MiddleMan' |
|---|
| 74 |
Object.send :remove_const, 'MiddleMan' |
|---|
| 75 |
MiddleMan = BackgrounDRb::MiddleManRailsProxy.init |
|---|
| 76 |
end |
|---|