require 'rails_helper' RSpec.describe ApplicationHandleInfo do describe '.use' do it 'requires a block' do expect { described_class.use('foo') } .to raise_error(ArgumentError) end context 'for a given starting ApplicationHandleInfo' do # This `around` block is identical to ApplicationHandleInfo.use. # # Q: So why don't we just use it here to DRY things up? # A: Because that's the method we're trying to test, dummy! # # Q: Why can't we do `before { ApplicationHandleInfo.current = 'foo' }` instead? # A: Because that would change `ApplicationHandleInfo.current` for all subsequent specs. # (RSpec uses database transactions to keep test environments clean, # but `ApplicationHandleInfo.current` lives outside of the database.) around do |example| original = described_class.current described_class.current = 'foo' example.run described_class.current = original end it 'runs the block using the given ApplicationHandleInfo' do described_class.use('bar') do expect(described_class.current).to eq('bar') end end it 'resets ApplicationHandleInfo to its original value' do described_class.use('bar') {} expect(described_class.current).to eq('foo') end context 'when an error is raised in the given block' do it 'does not rescue the error, and still resets ApplicationHandleInfo' do expect { described_class.use('bar') { raise } } .to raise_error(StandardError) .and not_change(described_class, :current) end end end end end