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,但这伪造了测试,因为我必须存根它接收到的 newcall 方法。

有办法实现吗?

首先在服务上创建一个 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