I have the below Ruby class, and and test which works with this piece of code.
require 'logger'
class MyAddKlass
  attr_reader :data
  def my_method(x)
    @data = x * 2
    logger = Logger.new($stdout)
    logger.info @data
  end
end
My Rspec code. This code I wrote basically to test how and_call_original but I stepped into something which now became my primary interest to know first.
# frozen_string_literal: true
require_relative '../my_add_klass'
describe MyAddKlass do
  it 'calls the original method' do
    obj = described_class.new
    allow_any_instance_of(Logger).to receive(:info).and_call_original
    expect { obj.my_method(5) }.to output(/.*10/).to_stdout
  end
end
result of the test is green…
 bundle exec rspec ./spec/my_add_klass_spec.rb
.
Finished in 0.04966 seconds (files took 0.40982 seconds to load)
1 example, 0 failures
Now once, I replace $stdout with STDOUT, my test fails.
 bundle exec rspec ./spec/my_add_klass_spec.rb
I, [2024-09-11T00:01:38.039070 #13801]  INFO -- : 10
F
Failures:
  1) MyAddKlass calls the original method
     Failure/Error: expect { obj.my_method(5) }.to output(/.*10/).to_stdout
       expected block to output /.*10/ to stdout, but output nothing
       Diff:
       @@ -1 +1 @@
       -/.*10/
       +""
     # ./spec/my_add_klass_spec.rb:9:in `block (2 levels) in <top (required)>'
Finished in 0.05945 seconds (files took 0.13727 seconds to load)
1 example, 1 failure
Failed examples:
rspec ./spec/my_add_klass_spec.rb:5 # MyAddKlass calls the original method
Why this code behaving differently with STDOUT and $stdout?