使用 RSpec 测试 DeserializationError

Posted

技术标签:

【中文标题】使用 RSpec 测试 DeserializationError【英文标题】:Use RSpec to test for DeserializationError 【发布时间】:2017-06-28 03:31:42 【问题描述】:

我有一份正在排队的工作。有时,与该作业关联的记录会在作业运行之前被销毁。

为了解决在作业执行期间引发的任何ActiveJob::DeserializationError,我在作业中添加了以下内容:

rescue_from(ActiveJob::DeserializationError) do |exception|
  exception.original_exception == ActiveRecord::RecordNotFound
end

我想对此进行测试,以便我可以验证当作业运行时记录已被销毁时不会引发ActiveJob::DeserializationError

为了开始测试,我删除了上面的函数,并决定确保我可以测试ActiveJob::DeserializationError 确实被抛出了。规范是:

it "raises DeserializationError when a record is destroyed before perform" do
  record = create(:record)

  record.destroy

  expect RecordDeletionJob.perform_later(record) .to raise_error(ActiveJob::DeserializationError)
end

令我惊讶的是,规范失败了,因为没有提出任何内容。这是不正确的。如果没有rescue_from 方法,它应该会引发ActiveJob::DeserializationError

我认为问题在于记录没有被重新加载,但我不知道如何在记录销毁后重新加载记录以及之后如何测试ActiveJob::DeserializationError

在作业运行时记录不存在的情况下,如何测试ActiveJob::DeserializationError不抛出?

【问题讨论】:

如果将perform_later 替换为perform_now 是否有效? 它没有。这可能是我最初的问题中的一个错误,因为我实际上开始使用 perform_now 进行测试 【参考方案1】:

我是这样测试的:

it "retries 5 times" do
  serialized_args = [
        
          "_aj_ruby2_keywords" => [
            "entity",
          ],
          "entity" => 
            "_aj_globalid"=> "gid://app/Entity/6ec11df7-ccf3-45ee-bc1c-f61821ef0aa2"
          
        
      ]
  subject.serialized_arguments = serialized_args
  4.times  subject.perform_now 
  expect  subject.perform_now .to raise_exception(ActiveJob::DeserializationError)
end

【讨论】:

以上是关于使用 RSpec 测试 DeserializationError的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 RSpec 测试 ActionText?

rspec 使用 draper Decorator 测试视图

使用 Rspec 测试 Rails 3.1 可安装引擎

使用现有的 TestUnit 测试和 Simplecov 覆盖运行 RSpec

如何在 rspec 中运行单个测试?

SystemStackError - 堆栈级别太深;在 Rspec 测试中,使用acts_as_audited、Rspec、数据库清理器