I have the following Ruby class I want to test:
class Logger
# ...
def process
X.process
rescue StandardError => e
::Rails.logger.error('Progname') { 'Could not produce the audit log' }
::Rails.logger.error('Progname') { e.message }
::Rails.logger.error('Progname') { e.backtrace.join("\n") }
end
end
And my RSpec test that currently works:
require 'spec_helper'
describe Logger do
before do
stub_const('Rails', double('Rails', logger: rails_logger))
end
let(:rails_logger) { instance_double(Logger, error: nil) }
describe '#process' do
subject(:process) { log.process }
context 'when an exception occurs' do
let(:error) do
StandardError.new('Something went wrong')
end
before do
allow(X).to receive(:process).and_raise(error)
allow(error).to receive(:backtrace)
.and_return(['backtrace:1', 'backtrace:2'])
end
it 'logs an error message' do
expect(rails_logger).to(receive(:error).with('Progname')) do |&block|
expect(block.call).to eq('Could not produce the audit log')
end
expect(rails_logger).to(receive(:error).with('Progname')) do |&block|
expect(block.call).to eq('Something went wrong')
end
expect(rails_logger).to(receive(:error).with('Progname')) do |&block|
expect(block.call).to eq("backtrace:1\nbacktrace:2")
end
process
end
end
end
end
Now I want to use the have_received
form instead so I changed my code to:
it 'logs an error message' do
process
expect(rails_logger).to(have_received(:error).with('Progname')) do |&block|
expect(block.call).to eq('Could not produce the audit log')
end
expect(rails_logger).to(have_received(:error).with('Progname')) do |&block|
expect(block.call).to eq('Something went wrong')
end
expect(rails_logger).to(have_received(:error).with('Progname')) do |&block|
expect(block.call).to eq("backtrace:1\nbacktrace:2")
end
end
but the block evaluation fails:
Failure/Error: expect(block.call).to eq('Could not produce the audit log')
expected: "Could not produce the audit log"
got: "Something went wrong"
It seems the strategy of the block evaluation is different there and if the expect within the block fails, instead of trying another expectation it fails immediately. I don't know how to rewrite my existing code.
Thanks.