一尘不染

rspec:如何测试redis#subscribe代码?

redis

给出类似的东西:

class MyClass
  def subscribe
    $redis.subscribe('channel') do |on|
       on.message do |channel, msg|
         Something.create(msg)
       end
    end
  end
end

如何测试MyClass执行subscribe时它将Something.create针对通道上收到的每条消息运行?


阅读 230

收藏
2020-06-20

共1个答案

一尘不染

您拥有的这段代码不是很容易测试。首先,绝对要摆脱这个全局$redis变量。相反,在构造函数中接受redis实例。

class MyClass
  attr_reader :redis

  def initialize(redis)
    @redis = redis
  end

  def subscribe
    redis.subscribe('channel') do |on|
       on.message do |channel, msg|
         Something.create(msg)
       end
    end
  end
end

然后在测试中,您可以制作一个完全可以控制但与您使用的api一致的虚拟redis。遵循以下原则:

class DummyRedis
  def subscribe(&block)
    @block = block
  end

  def trigger_on
    @block.call make_on_message
  end
end


fake_redis = DummyRedis.new

expect {
  mc = MyClass.new(fake_redis)
  mc.subscribe
  fake_redis.trigger_on
}.to change{Something.count}.from(0).to(1)

这种很酷的技术称为“依赖注入”(或者像某些人所说的那样,“将参数传递给构造函数”)。

2020-06-20