diff --git a/lib/mock_redis.rb b/lib/mock_redis.rb index 767fb5f..78e9c03 100644 --- a/lib/mock_redis.rb +++ b/lib/mock_redis.rb @@ -22,6 +22,7 @@ class MockRedis :path => nil, :timeout => 5.0, :password => nil, + :logger => nil, :db => 0, :time_class => Time, }.freeze @@ -65,6 +66,10 @@ def db options[:db] end + def logger + options[:logger] + end + def time_at(timestamp) options[:time_class].at(timestamp) end @@ -86,7 +91,9 @@ def respond_to?(method, include_private = false) end ruby2_keywords def method_missing(method, *args, &block) - @db.send(method, *args, &block) + logging([[method, *args]]) do + @db.send(method, *args, &block) + end end def initialize_copy(source) @@ -139,4 +146,28 @@ def _parse_options(options) options end + + def logging(commands) + return yield unless logger&.debug? + + begin + commands.each do |name, *args| + logged_args = args.map do |a| + if a.respond_to?(:inspect) then a.inspect + elsif a.respond_to?(:to_s) then a.to_s + else + # handle poorly-behaved descendants of BasicObject + klass = a.instance_exec { (class << self; self end).superclass } + "\#<#{klass}:#{a.__id__}>" + end + end + logger.debug("[MockRedis] command=#{name.to_s.upcase} args=#{logged_args.join(' ')}") + end + + t1 = Time.now + yield + ensure + logger.debug("[MockRedis] call_time=%0.2f ms" % ((Time.now - t1) * 1000)) if t1 + end + end end diff --git a/spec/mock_redis_spec.rb b/spec/mock_redis_spec.rb index fbdb373..bdec2be 100644 --- a/spec/mock_redis_spec.rb +++ b/spec/mock_redis_spec.rb @@ -81,4 +81,13 @@ end end end + + describe 'supplying a logger' do + it 'logs redis commands' do + logger = double('Logger', debug?: true, debug: nil) + mock_redis = MockRedis.new(logger: logger) + expect(logger).to receive(:debug).with(/command=HMGET args="hash" "key1" "key2"/) + mock_redis.hmget("hash", "key1", "key2") + end + end end