From 1db709ecbed2d4982a46560a4106de42995edc7a Mon Sep 17 00:00:00 2001 From: Jon Rowe Date: Wed, 17 Jul 2024 12:31:20 +0100 Subject: [PATCH] Protect against mocking Thread.current --- lib/rspec/support.rb | 6 +++++- spec/rspec/support_spec.rb | 7 +++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/rspec/support.rb b/lib/rspec/support.rb index 36325570..ace97b8e 100644 --- a/lib/rspec/support.rb +++ b/lib/rspec/support.rb @@ -2,6 +2,10 @@ class Thread attr_accessor :__rspec_local_data + + class << self + alias __current_for_rspec current + end end module RSpec @@ -96,7 +100,7 @@ def self.class_of(object) # A single thread local variable so we don't excessively pollute that namespace. def self.thread_local_data - Thread.current.__rspec_local_data ||= {} + Thread.__current_for_rspec.__rspec_local_data ||= {} end # @api private diff --git a/spec/rspec/support_spec.rb b/spec/rspec/support_spec.rb index 8321c002..5d67c4d4 100644 --- a/spec/rspec/support_spec.rb +++ b/spec/rspec/support_spec.rb @@ -205,6 +205,13 @@ def object.some_method end end + it "works when Thread.current is mocked" do + expect(Thread).to_not receive(:current) + + RSpec::Support.thread_local_data[:__for_test] = :oh_hai + expect(RSpec::Support.thread_local_data[:__for_test]).to eq :oh_hai + end + it "works when Thread#thread_variable_get and Thread#thread_variable_set are mocked" do expect(Thread.current).to receive(:thread_variable_set).with(:test, true).once.and_return(true) expect(Thread.current).to receive(:thread_variable_get).with(:test).once.and_return(true)