Help us understand the problem. What is going on with this article?

[RSpec] 特定の spec / context でのみモジュールを include したい場合の実装と検証

More than 1 year has passed since last update.

背景

下記の2点の要件があるテストを書こうとした
1. 特定の feature / context / describe ブロック内のみ ActiveJob::TestHelper を include して有効化したい。
2. そのブロック内でのみテスト対応した queue_adapter (:testアダプタ?) を利用し、それ以外ではデフォルト (当方の環境では :delayed_job) のままにしておきたい

問題

そこそこの規模のプロジェクトでテスト書いていたら、どこかで :delayed_job アダプタ前提のテストが実装されている可能性があるが、自分で新規に追加したテストでは job queue の検証をしたいため ActiveJob::TestHelper のメソッドを呼んだり queue_adapter:test に変えたくなった。
そのため他人が書いたコードに影響しないよう、適用範囲を絞ったモジュールインクルードと queue_adapter の変更をできる方法を探った。

結論

  1. module を mixin したいブロックで include してあげれば適用範囲がそのブロックに限定されるからOK
  2. ActiveJob::TestHelper を include すれば明示的に queue_adapter を切り替える必要がない。 ActiveJob::TestHelper が適宜 queue_adapter を調整して queue テスト可能にしてくれる。

検証コード

https://gist.github.com/qpSHiNqp/5f877886120ae722f4273d1c40d7bbf0

modules_spec.rb
require 'spec_helper'

describe RSpec, 'module isolation' do
  module Example1
    def hoge
      "example1"
    end
  end
  module Example2
    def hoge
      "example2"
    end
  end

  context '#include Example1' do
    include Example1
    it 'should respond to :hoge and return "example1"' do
      expect(self).to respond_to(:hoge)
      expect(hoge).to eq("example1")
    end
  end
  context '#include Example2' do
    include Example2
    it 'should respond to :hoge and return "example2"' do
      expect(self).to respond_to(:hoge)
      expect(hoge).to eq("example2")
    end
  end
  context '#include nothing' do
    it 'should not respond to :hoge' do
      expect(self).not_to respond_to(:hoge)
    end
  end
end

describe RSpec do
  before { ExampleJob.perform_later }

  context '#include ActiveJob::TestHelper' do
    include ActiveJob::TestHelper

    it 'should be available to call #have_been_enqueued' do
      expect { expect(ExampleJob).to have_been_enqueued }.not_to raise_error
    end

    it 'should be available to call #assert_enqueued_jobs' do
      expect(self).to respond_to(:assert_enqueued_jobs)
      assert_enqueued_jobs 1
    end

    it 'should change queue_adapter to :test' do
      expect(ActiveJob::Base.queue_adapter).to be_kind_of(ActiveJob::QueueAdapters::TestAdapter)
    end
  end

  context 'not #include ActiveJob::TestHelper' do
    it 'should not be available to call #have_been_enqueued' do
      expect { expect(ExampleJob).to have_been_enqueued }.to raise_error(StandardError)
    end

    it 'should not be available to call #assert_enqueued_jobs' do
      expect(self).not_to respond_to(:assert_enqueued_jobs)
      expect{assert_enqueued_jobs(1)}.to raise_error(StandardError)
    end

    it 'should not change queue_adapter to :test' do
      expect(ActiveJob::Base.queue_adapter).not_to be_kind_of(ActiveJob::QueueAdapters::TestAdapter)
    end
  end
end
qpSHiNqp
技術担当。 好きなものは、クルマ、サバゲー、ウィンタースポーツです。
onecareer
ワンランク上のキャリアを目指す学生のための新卒採用サービスONE CAREERの開発・運営会社
https://www.onecareer.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away