如何在RSpec的模型回调中测试救援块?

时间:2019-02-08 06:25:58

标签: ruby-on-rails rspec

我的模型中有一个after_save方法来调用一些后台任务。由于此任务取决于另一台正在运行的服务器,因此我认为在对另一台服务器的调用失败时创建回退以在主线程上执行任务是一个好主意。

这基本上是回调:

  def send_email
    MyJob.perform_async(self.id)
  rescue Errno::ECONNREFUSED
    MyJob.new.perform(self.id)
  end

现在,我想测试一下此行为。我尝试通过模拟MyJob并在perfrom_async方法上引发异常来进行尝试。但是,如何测试实例上是否正在调用perform?

我已经尝试过:

it "should use fallback to send e-mail after create when faktory is down" do
  job = class_double("MyJob").
  as_stubbed_const(:transfer_nested_constants => true)

  allow(job).to receive(:perform_async) { raise Errno::ECONNREFUSED }
  expect_any_instance_of(job).to receive(:perform)
  company_opt_out
end

谢谢

2 个答案:

答案 0 :(得分:1)

无需存根MyJob类

it "should use fallback to send e-mail after create when faktory is down" do
  allow(MyJob).to receive(:perform_async).and_raise(Errno::ECONNREFUSED)
  expect_any_instance_of(MyJob).to receive(:perform)
  company_opt_out
end

但请确保您的company_opt_out调用send_email方法

答案 1 :(得分:1)

在编写测试时,尽量不要使it块过载太多,因为当您或其他开发人员稍后再使用它时,它们将变得难以阅读。

  let(:job_instance) { instance_double(MyJob, perform: "Performing now") }

  before do
    allow(MyJob).to receive(:perform_async).and_return("Performing later")
    allow(MyJob).to receive(:new).and_return(job_instance)
  end

  it "performs the job later" do
    expect(send_email).to eq("Performing later")
  end

  context "when a network error is raised" do
    before { allow(MyJob).to receive(:perform_async).and_raise(Errno::ECONNREFUSED) }

    it "performs the job now" do
      expect(send_email).to eq("Performing now")
    end
  end