rspec: 如何测试redis#subscribe代码?
rspec: How to test redis#subscribe code?
给出类似的东西:
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
?
虽然这种方法没有使用实际测试,但我会执行以下操作并检查日志。
class MyClass
def subscribe
$redis.subscribe('channel') do |on|
on.message do |channel, msg|
event = Something.create(msg)
p event.persisted? ? "success" : "fail"
p event
end
end
end
end
您拥有的这段代码不太可测试。首先,绝对摆脱这个全局 $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)
这种很酷的技术称为依赖注入(或者,正如某些人所说,"passing parameters to constructors")。
好吧,它可以像
一样简单
describe MyClass do
it 'should create something' do
expect(Something).to receive(:create)
subject.subscribe
subject.trigger_message # you should trigger a message somehow
end
end
给出类似的东西:
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
?
虽然这种方法没有使用实际测试,但我会执行以下操作并检查日志。
class MyClass
def subscribe
$redis.subscribe('channel') do |on|
on.message do |channel, msg|
event = Something.create(msg)
p event.persisted? ? "success" : "fail"
p event
end
end
end
end
您拥有的这段代码不太可测试。首先,绝对摆脱这个全局 $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)
这种很酷的技术称为依赖注入(或者,正如某些人所说,"passing parameters to constructors")。
好吧,它可以像
一样简单describe MyClass do
it 'should create something' do
expect(Something).to receive(:create)
subject.subscribe
subject.trigger_message # you should trigger a message somehow
end
end