Reputation: 11920
I'm writing a Ruby gem, and below is the implementation of how I create a new Logger
.
My gem may or may not be used inside of Rails, so it tries to use Rails.logger
IF one exists.
require 'logger'
module MyLoggeer
def logger
@logger ||= rails_logger || Logger.new($stdout)
end
def rails_logger
if defined?(::Rails) && ::Rails.respond_to?(:logger) && !::Rails.logger.nil?
::Rails.logger
else
nil
end
end
end
My gem does not have Rails
defined anywhere as a constant. If I wanted to test the above logic with RSpec, is there a way for me to -
Rails
objectlogger
method?I suppose I could define a dummy class inside my spec files, but I was hoping there was a way to easily mock / stub this out instead.
Thanks!
Upvotes: 0
Views: 612
Reputation: 102443
With RSpec mocks you can use a double
(as in stunt double) to create a stand in for any object.
You then use allow
to allow the double to receive messages and expect
to set method expectations.
let(:logger) do
instance_double("Logger")
end
let(:rails) do
double("Rails")
end
before do
allow(rails).to receive(:logger).and_return(logger)
stub_const("Rails", rails)
end
You can also use instance doubles and class doubles to create doubles of existing classes - this will verify that you only call methods that actually exist on the class you are doubling.
stub_const
will stub the value of a constant for the duration of an example.
Upvotes: 3