Here is a solution that
- works for request specs,
- works with Rails 5, and
- does not involve private API of Rails (like
process).
Here's the RSpec configuration:
module DefaultFormat extend ActiveSupport::Concern included do let(:default_format) { 'application/json' } prepend RequestHelpersCustomized end module RequestHelpersCustomized l = lambda do |path, **kwarg| kwarg[:headers] = {accept: default_format}.merge(kwarg[:headers] || {}) super(path, **kwarg) end %w(get post patch put delete).each do |method| define_method(method, l) end end end RSpec.configure do |config| config.include DefaultFormat, type: :request end
Verified with
describe 'the response format', type: :request do it 'can be overridden in request' do get some_path, headers: {accept: 'text/plain'} expect(response.content_type).to eq('text/plain') end context 'with default format set as HTML' do let(:default_format) { 'text/html' } it 'is HTML in the context' do get some_path expect(response.content_type).to eq('text/html') end end end
FWIW, The RSpec configuration can be placed:
Directly in spec/spec_helper.rb. This is not suggested; the file will be loaded even when testing library methods in lib/.
Directly in spec/rails_helper.rb.
(my favorite) In spec/support/default_format.rb, and be loaded explicitly in spec/rails_helper.rb with
require 'support/default_format'
In spec/support, and be loaded by
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
which loads all the files in spec/support.
This solution is inspired by knoopx's answer. His solution doesn't work for request specs, and alias_method_chain has been deprecated in favor of Module#prepend.