Skip to content

RSpec leaks ActiveSupport::ExecutionContext between specs. #2644

Closed
@BobbyMcWho

Description

@BobbyMcWho

What Ruby, Rails and RSpec versions are you using?

Ruby version: 2.7
Rails version: 7.0.4
RSpec version: ~> 6.0

Observed behaviour

When using the Rails 7+ built in error reporter Rails.error, any context set during a spec leaks to the next spec.

I've resolved this by

config.before(:each)
  ActiveSupport::ExecutionContext.clear
end

While this works for me, it feels like a tripping point for folks using rspec-rails on rails >= 7.0

Expected behaviour

ExecutionContext should be cleared between each spec, so that context does not leak between specs.

Can you provide an example app?

require 'bundler/inline'

gemfile(true) do
  source 'https://rubygems.org'
  gem 'rails', '7.0.4'
  gem 'rspec-rails', '~> 6.0.0'
end

require 'rails'
require 'action_controller/railtie'

class MyApplication < Rails::Application; end

class PagesController < ActionController::Base
  include Rails.application.routes.url_helpers

  def index
    render inline: "SOME HTML"
  end
end

MyApplication.routes.draw do
  get '/pages', to: 'pages#index'
end

require 'rspec/rails'
require "rspec/autorun"

def app
  MyApplication
end

RSpec.describe "First non-controller test" do
  it "does not leak the controller context" do
    expect(ActiveSupport::ExecutionContext.to_h).to eq({})
  end
end

RSpec.describe PagesController, type: :controller do
  it "runs a controller test" do
    get :index
    expect(response.body).to eq("SOME HTML")
    expect(ActiveSupport::ExecutionContext.to_h).to eq({ controller: controller })
  end
end

# fails
RSpec.describe "Second non-controller test" do
  it "does not leak the controller context" do
    expect(ActiveSupport::ExecutionContext.to_h).to eq({})
  end
end

RSpec.describe "A context test" do
  before do
    ActiveSupport::ExecutionContext.clear
    Rails.error.set_context(foo: "bar")
  end

  it "sets the context" do
    expect(ActiveSupport::ExecutionContext.to_h).to eq({foo: "bar"})
  end
end

# fails
RSpec.describe "A second context test" do
  it "does not leak the context" do
    expect(ActiveSupport::ExecutionContext.to_h).to eq({})
  end
end

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions