Marc Greenstock Marc Greenstock - 3 months ago 14
Ruby Question

How to share RSpec let variables between shared contexts?

I'm trying to DRY my RSpec request specs by using shared contexts. I'd like to share

let
variables between shared contexts so that they inherit and extend from one another.

Rspec.shared_context 'JSON request' do
let(:headers) do
{
'Accept' => 'application/json'
}
end
end

Rspec.shared_context 'Authenticated request' do
let(:headers) do
super().merge('Authorization' => "Bearer #{token}")
end
end

Rspec.describe 'user management' do
let(:token) { create(:oauth_token) }

include_context 'JSON request'
include_context 'Authenticated request'

it 'responds with a 200 ok' do
get '/user', headers: headers
expect(response).to have_http_status(:ok)
end
end


Declaring
token
works as expected, but using
super()
to override
headers
returns a
NoMethodError
suggesting
super()
is nil.

Answer

I'm not aware of a way to refer to the currently defined value of a let variable in a let block. (When I try it I get "stack level too deep".) I'd do what you're trying to do this way:

Rspec.shared_context 'JSON request' do
  let(:common_headers) do
    {
      'Accept' => 'application/json'
    }
  end
  let(:headers) { common_headers }
end

Rspec.shared_context 'Authenticated request' do
  let(:headers) do
    common_headers.merge('Authorization' => "Bearer #{token}")
  end
end