Этот код у вас есть, это не очень проверяемо. Прежде всего, полностью избавиться от этой глобальной переменной $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
Затем в тестах вы можете сделать манекен Redis, что вы можете полностью контролировать, но который соответствует API, который вы используете. Что-то вдоль этих линий:
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)
Этот прохладный прием называется Dependency Injection (или, как некоторые люди выразились, «передача параметров в конструкторах»).
Почему вы используете '$ redis' как глобальные переменные? –
Теоретически говоря, у вас есть два способа сделать это: 1- Mocking Redis object 2- Проверить, был ли msg опубликован для канала. – moeabdol
Alexey: чтобы было проще понять код, в моем реальном коде это @store, но тогда мне нужно было бы поместить код init в образец, и я хотел бы использовать голой случай использования кости. – Alain