1

Rails app has the controller with actions which response html and json formats. In specs I should specify format: 'json' for all requests:

it 'returns list of entities' do
  get :list, format: 'json'
  ...
end

Is there a way to avoid write format: 'json' for every example? Something like this:

context 'json', format: 'json' do
  it 'returns list of entities' do
    get :list
    ...
  end
end
max
  • 96,212
  • 14
  • 104
  • 165
vovan
  • 1,460
  • 12
  • 22
  • 1
    Edited the title for search-ability. This is also a potential duplicate of https://stackoverflow.com/questions/11022839/set-rspec-default-get-request-format-to-json/39399215 - which currently does not seem to have a currently working answer. – max Nov 16 '18 at 17:26

1 Answers1

2

This is adapted from https://stackoverflow.com/a/39399215/544825 but for controller specs.

Tested on: RSpec 3.8, Rails 5.2.1

This module uses metaprogramming to redefine the get, post etc methods and a memoized let helper (default_format) instead of metadata.

It basically just merges format: default_format into the arguments and calls the original implementation.

# spec/support/default_format.rb
module DefaultFormat
  extend ActiveSupport::Concern

  included do
    let(:default_format) {}
    prepend RequestHelpersCustomized
  end

  module RequestHelpersCustomized
    l = lambda do |path, **kwargs|
      kwargs[:format] ||= default_format if default_format
      super(path, kwargs)
    end
    %w(get post patch put delete).each do |method|
      define_method(method, l)
    end
  end
end

And then include this module in your rails_helper.rb or spec_helper.rb(if you only have one test setup file):

require 'support/default_format'

RSpec.configure do |config|
  # ...
  config.include DefaultFormat, type: :controller
  # ...
end

Usage:

context 'json' do
  let(:default_format) { :json }
end

I don't think this can be done with example metadata as its not available from within an example (which is where the get method is called).

max
  • 96,212
  • 14
  • 104
  • 165