如何为Rails Jobs编写Rspec测试

3

您好,我正在使用 Ruby-2.5.0 和 Rails 5 开发一个 RoR 项目。我正在使用 AWS SQS。我创建了以下作业:

class ReceiptsProcessingJob < ActiveJob::Base
  queue_as 'abc'

  def perform(receipt_id)
    StoreParserInteractor.process_reciept(receipt_id)
  end
end

现在我想为它编写单元测试。我尝试了以下方式:-
# frozen_string_literal: true

require 'rails_helper'

describe ReceiptsProcessingJob do

  describe "#perform_later" do
    it "scan a receipt" do
      ActiveJob::Base.queue_adapter = :test
      expect {
        ReceiptsProcessingJob.perform_later(1)
      }.to have_enqueued_job
    end
  end
end

但它不包括 StoreParserInteractor.process_reciept(receipt_id)。请帮忙如何处理这个问题。提前感谢您的帮助。
2个回答

1
这个例子是在测试工作类。你需要为StoreParserInteractor编写规范,并测试process_reciept方法。
大致如下(伪代码):
describe StoreParserInteractor do
  describe "#process_receipt" do
    it "does that" do
      result = StoreParserInteractor.process_receipt(your_data_here)
      expect(result to be something)...
    end
  end
end

但是,Rails指南建议使用这种类型的测试:


assert_enqueued_with(job: ReceiptsProcessingJob) do
  StoreParserInteractor.process_reciept(receipt_id)
end

也许这也会增加代码覆盖率。

谢谢,但我已经为StoreParserInteractor编写了规范,并测试了process_reciept。这个文件已经覆盖了100%。 - awsm sid
@awsmsid,你能否提供覆盖率工具的输出以及StoreParserInteractor类的实现? - manitu

0
在我看来,你不应该测试ActiveJob本身,而是它背后的逻辑。
你应该为StoreParserInteractor#process_reciept编写一个测试。将ActiveJob视为“外部框架”,你不需要测试其内部(例如作业是否已排队)。
正如kitschmaster所说,简而言之,不要测试ActiveJob类。

如果我不测试ActiveJob,它仍然显示ActiveJob的覆盖率为75%。我已经编写了StoreParserInteractor#process_reciept的测试,但仍然无效。 - awsm sid
你可以从覆盖范围中移除ActiveJob。 - Luiz E.
我不想删除它。 - awsm sid
看起来 ReceiptsProcessingJob.perform_later(receipt.id) 这一行我还没有涉及到。我已经使用了 allow(ReceiptsProcessingJob).to receive(:perform_later).with(any_args) { receipt_with_max_size }。 - awsm sid
我也尝试了像这样的 expect(StoreParserInteractor).to receive(:process_receipt).with(receipt_id) 但是我收到了一个错误 期望: 1 次参数为: (3) 收到: 0 次 - awsm sid

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接