首页 > 解决方案 > rspec 规范仅在整个测试套件中运行时失败 - 单独运行时通过

问题描述

我有一个几乎毫无意义的工人测试规范:

require 'rails_helper'
require 'sidekiq/testing'
Sidekiq::Testing.fake!

RSpec.describe FetchArticleContentWorker, type: :worker do

  describe "Sidekiq Worker" do

    before(:each) do
      allow_any_instance_of(DataSource).to receive(:subscribe).and_return(true)
      allow_any_instance_of(FetchArticleContentWorker).to receive(:perform).and_return(true)
    end
    let(:user) { FactoryBot.create(:user) }
    let(:data_source) { FactoryBot.create(:data_source) }
    let(:article) { FactoryBot.create(:article, data_source_id: data_source.id) }

    it "should respond to #perform" do
      expect(FetchArticleContentWorker.new).to respond_to(:perform)
    end

    describe "fetch article content worker" do

      before do
        Sidekiq::Worker.clear_all
      end

      it "increase the worker job size" do
        expect { FetchArticleContentWorker.perform_async(article.url) }.to change(FetchArticleContentWorker.jobs, :size).by(1)
      end

      it "assert that jobs were pushed on to the queue" do
        assert_equal 0, FetchArticleContentWorker.jobs.size
        FetchArticleContentWorker.perform_async(article.url)
        assert_equal 1, FetchArticleContentWorker.jobs.size
      end

      it "job runs successfully" do
        expect(FetchArticleContentWorker.new.perform(article.url)).to eq(true)
      end
    end
  end
end

无论出于何种原因,这组规范突然开始失败,但只是在作为整个测试套件的一部分运行时。如果我自己直接运行这个测试,它每次都通过。

当与bundle exec rspec(做整个套件)一起运行时,我在这个特定的测试中遇到以下失败:

Failures:                                                                      
                                                                               
  1) FetchArticleContentWorker Sidekiq Worker fetch article content worker increase the worker job size
     Failure/Error: expect { FetchArticleContentWorker.perform_async(article.url) }.to change(FetchArticleContentWorker.jobs, :size).by(1)
       expected `Array#size` to have changed by 1, but was changed by 0                
     # ./spec/workers/fetch_article_content_worker_spec.rb:29:in `block (4 levels) in <top (required)>'
     # ./spec/rails_helper.rb:48:in `block (3 levels) in <top (required)>'
     # /usr/local/bundle/gems/database_cleaner-1.8.4/lib/database_cleaner/generic/base.rb:16:in `cleaning'
     # /usr/local/bundle/gems/database_cleaner-1.8.4/lib/database_cleaner/configuration.rb:87:in `block (2 levels) in cleaning'
     # /usr/local/bundle/gems/database_cleaner-1.8.4/lib/database_cleaner/configuration.rb:88:in `cleaning'
     # ./spec/rails_helper.rb:47:in `block (2 levels) in <top (required)>'

  2) FetchArticleContentWorker Sidekiq Worker fetch article content worker assert that jobs were pushed on to the queue
     Failure/Error: assert_equal 1, FetchArticleContentWorker.jobs.size

     Minitest::Assertion:
       Expected: 1
         Actual: 0
     # /usr/local/bundle/gems/minitest-5.14.0/lib/minitest/assertions.rb:183:in `assert'
     # /usr/local/bundle/gems/minitest-5.14.0/lib/minitest/assertions.rb:218:in `assert_equal'
     # ./spec/workers/fetch_article_content_worker_spec.rb:35:in `block (4 levels) in <top (required)>'
     # ./spec/rails_helper.rb:48:in `block (3 levels) in <top (required)>'
     # /usr/local/bundle/gems/database_cleaner-1.8.4/lib/database_cleaner/generic/base.rb:16:in `cleaning'
     # /usr/local/bundle/gems/database_cleaner-1.8.4/lib/database_cleaner/configuration.rb:87:in `block (2 levels) in cleaning'
     # /usr/local/bundle/gems/database_cleaner-1.8.4/lib/database_cleaner/configuration.rb:88:in `cleaning'
     # ./spec/rails_helper.rb:47:in `block (2 levels) in <top (required)>'

似乎这些工作规范仅在以前运行使用 turnip 的功能时才会失败。

标签: ruby-on-railsrspec

解决方案


我最终发现了我认为的问题。

在我的萝卜步骤文件中,我将 sidekick 设置为内联:

  # set sidekiq to inline
  require 'sidekiq/testing'
  Sidekiq::Testing.inline!

而且,即使我Sidekiq::Testing.fake!在上述规范文件中进行设置,它似乎也没有“接受”。

当我fake!进入 before 块时,这似乎解决了问题:

  describe "Sidekiq Worker" do

    before(:each) do
      allow_any_instance_of(DataSource).to receive(:subscribe).and_return(true)
      allow_any_instance_of(FetchArticleContentWorker).to receive(:perform).and_return(true)
      Sidekiq::Testing.fake!
    end

...

我不知道为什么这是修复,但这修复了它。


推荐阅读