Rails 测试作业并提出错误(如果有)
Rails test job and raise errors if any
我有一份工作,目前正在使用 RSpec:
进行测试
# app/jobs/do_something_job.rb
class DoSomethingJob < ApplicationJob
def perform(a, b, c)
Service.new(a, b, c).call
end
end
示例文件如下所示:
require 'spec_helper'
describe DoSomethingJob do
it do
expect { described_class.perform_later(a, b, c) }.to have_enqueued_job
end
end
该示例当然成功了,无论 perform
方法体内发生什么,它都会将作业排队。
现在,如果我更新 Service
class,比如删除其 initialize
方法中的一个参数,就这样:
class Service
def initialize(a, b)
...
end
end
而且我没有更新作业示例,它无论如何都会成功,因为作业已排队。我想做的是测试 DoSomethingJob#perform
的主体执行时没有错误,而不了解 Service
本身的细节(它有自己的测试)。
我尝试模拟服务并使用 expect { ... }.not_to raise_error
,但这伪造了测试,因为我必须存根它接收到的 new
和 call
方法。
有办法实现吗?
首先在服务上创建一个 class 方法,这样您就不必存根实例了:
class Service
def self.call(a, b, c)
new(a, b, c).call
end
end
# app/jobs/do_something_job.rb
class DoSomethingJob < ApplicationJob
def perform(a, b, c)
Service.call(a, b, c)
end
end
然后只需对您希望该方法执行的操作(在本例中称为协作者)寄予期望并立即执行该工作:
describe DoSomethingJob do
it "calls Service with a, b, c" do
expect(Service).to receive(:call).with(1, 2, 3).and_call_original
DoSomethingJob.perform_now(1, 2, 3)
end
end
我有一份工作,目前正在使用 RSpec:
进行测试# app/jobs/do_something_job.rb
class DoSomethingJob < ApplicationJob
def perform(a, b, c)
Service.new(a, b, c).call
end
end
示例文件如下所示:
require 'spec_helper'
describe DoSomethingJob do
it do
expect { described_class.perform_later(a, b, c) }.to have_enqueued_job
end
end
该示例当然成功了,无论 perform
方法体内发生什么,它都会将作业排队。
现在,如果我更新 Service
class,比如删除其 initialize
方法中的一个参数,就这样:
class Service
def initialize(a, b)
...
end
end
而且我没有更新作业示例,它无论如何都会成功,因为作业已排队。我想做的是测试 DoSomethingJob#perform
的主体执行时没有错误,而不了解 Service
本身的细节(它有自己的测试)。
我尝试模拟服务并使用 expect { ... }.not_to raise_error
,但这伪造了测试,因为我必须存根它接收到的 new
和 call
方法。
有办法实现吗?
首先在服务上创建一个 class 方法,这样您就不必存根实例了:
class Service
def self.call(a, b, c)
new(a, b, c).call
end
end
# app/jobs/do_something_job.rb
class DoSomethingJob < ApplicationJob
def perform(a, b, c)
Service.call(a, b, c)
end
end
然后只需对您希望该方法执行的操作(在本例中称为协作者)寄予期望并立即执行该工作:
describe DoSomethingJob do
it "calls Service with a, b, c" do
expect(Service).to receive(:call).with(1, 2, 3).and_call_original
DoSomethingJob.perform_now(1, 2, 3)
end
end