给出类似的东西:
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针对通道上收到的每条消息运行?
MyClass
subscribe
Something.create
您拥有的这段代码不是很容易测试。首先,绝对要摆脱这个全局$redis变量。相反,在构造函数中接受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)
这种很酷的技术称为“依赖注入”(或者像某些人所说的那样,“将参数传递给构造函数”)。