背景
下記の2点の要件があるテストを書こうとした
- 特定の
feature/context/describeブロック内のみActiveJob::TestHelperを include して有効化したい。 - そのブロック内でのみテスト対応した
queue_adapter(:testアダプタ?) を利用し、それ以外ではデフォルト (当方の環境では:delayed_job) のままにしておきたい
問題
そこそこの規模のプロジェクトでテスト書いていたら、どこかで :delayed_job アダプタ前提のテストが実装されている可能性があるが、自分で新規に追加したテストでは job queue の検証をしたいため ActiveJob::TestHelper のメソッドを呼んだり queue_adapter を :test に変えたくなった。
そのため他人が書いたコードに影響しないよう、適用範囲を絞ったモジュールインクルードと queue_adapter の変更をできる方法を探った。
結論
- module を mixin したいブロックで
includeしてあげれば適用範囲がそのブロックに限定されるからOK -
ActiveJob::TestHelperを include すれば明示的にqueue_adapterを切り替える必要がない。
ActiveJob::TestHelperが適宜queue_adapterを調整して queue テスト可能にしてくれる。
検証コード
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