mock_redis icon indicating copy to clipboard operation
mock_redis copied to clipboard

Use MockRedis with Redis::Connection.drivers

Open 23tux opened this issue 3 years ago • 0 comments

I'm trying to migrate from fakeredis to mock_redis, because the fakeredis gem is pretty outdated and I guess not maintained anymore. I now face the problem, that we often use Redis.new at the class level like this

class Foo
  # ...
  REDIS = Redis.new(credentials)
  # ...
end

but stubbing out Redis.new in RSpec like this doesn't work, as it is too late and the constant is already set:

config.before do
  allow(Redis).to receive(:new).and_return(MockRedis.new)
end

I wondered how Fakeredis did it, and found this line

https://github.com/magicguitarist/fakeredis/blob/509822e07289a7f78e340b8be757fae662c0e0de/lib/redis/connection/memory.rb#L1601-L1602

This is the same method as redis-rb does it

https://github.com/redis/redis-rb/blob/4e9d73d3bb47831fe720cbce7c47cb11dd3f4de9/lib/redis/connection/ruby.rb#L436-L437

So I was wondering, if I could also use MockRedis like this. Unfortunately, doing this results in an error, when the client is created:

require "redis"
require "mock_redis"
Redis::Connection.drivers << MockRedis
Redis.new.get("*")

=> NoMethodError: undefined method `write' for #<MockRedis::Database:0x000055bbe31c7d08>
/usr/local/bundle/gems/mock_redis-0.34.0/lib/mock_redis/multi_db_wrapper.rb:21:in `method_missing'
/usr/local/bundle/gems/mock_redis-0.34.0/lib/mock_redis/expire_wrapper.rb:17:in `method_missing'
/usr/local/bundle/gems/mock_redis-0.34.0/lib/mock_redis/transaction_wrapper.rb:30:in `method_missing'
/usr/local/bundle/gems/mock_redis-0.34.0/lib/mock_redis/pipelined_wrapper.rb:27:in `method_missing'
/usr/local/bundle/gems/mock_redis-0.34.0/lib/mock_redis.rb:99:in `block in method_missing'
/usr/local/bundle/gems/mock_redis-0.34.0/lib/mock_redis.rb:155:in `logging'
/usr/local/bundle/gems/mock_redis-0.34.0/lib/mock_redis.rb:98:in `method_missing'
/usr/local/bundle/gems/redis-4.8.0/lib/redis/client.rb:320:in `block in write'
/usr/local/bundle/gems/redis-4.8.0/lib/redis/client.rb:299:in `io'
/usr/local/bundle/gems/redis-4.8.0/lib/redis/client.rb:318:in `write'
/usr/local/bundle/gems/redis-4.8.0/lib/redis/client.rb:276:in `block (3 levels) in process'
/usr/local/bundle/gems/redis-4.8.0/lib/redis/client.rb:270:in `each'
/usr/local/bundle/gems/redis-4.8.0/lib/redis/client.rb:270:in `block (2 levels) in process'
/usr/local/bundle/gems/redis-4.8.0/lib/redis/client.rb:420:in `ensure_connected'
/usr/local/bundle/gems/redis-4.8.0/lib/redis/client.rb:269:in `block in process'
/usr/local/bundle/gems/redis-4.8.0/lib/redis/client.rb:356:in `logging'
/usr/local/bundle/gems/redis-4.8.0/lib/redis/client.rb:268:in `process'
/usr/local/bundle/gems/redis-4.8.0/lib/redis/client.rb:161:in `call'
/usr/local/bundle/gems/redis-4.8.0/lib/redis/client.rb:144:in `block in connect'
/usr/local/bundle/gems/redis-4.8.0/lib/redis/client.rb:344:in `with_reconnect'
/usr/local/bundle/gems/redis-4.8.0/lib/redis/client.rb:114:in `connect'
/usr/local/bundle/gems/redis-4.8.0/lib/redis/client.rb:417:in `ensure_connected'
/usr/local/bundle/gems/redis-4.8.0/lib/redis/client.rb:269:in `block in process'
/usr/local/bundle/gems/redis-4.8.0/lib/redis/client.rb:356:in `logging'
/usr/local/bundle/gems/redis-4.8.0/lib/redis/client.rb:268:in `process'
/usr/local/bundle/gems/redis-4.8.0/lib/redis/client.rb:161:in `call'
/usr/local/bundle/gems/redis-4.8.0/lib/redis.rb:270:in `block in send_command'
/usr/local/bundle/gems/redis-4.8.0/lib/redis.rb:269:in `synchronize'
/usr/local/bundle/gems/redis-4.8.0/lib/redis.rb:269:in `send_command'
/usr/local/bundle/gems/redis-4.8.0/lib/redis/commands/strings.rb:191:in `get'

Does anyone know if using Redis::Connection.drivers with redis is possible? The only alternative is trying to convert every constant to a class method, which I'd like to avoid.

23tux avatar Nov 03 '22 11:11 23tux