# nabbed from em-hiredis, who got it from redis-rb, thanks! require "socket" module RedisMock def self.start(port = 6380) server = TCPServer.new("127.0.0.1", port) loop do session = server.accept while line = session.gets parts = Array.new(line[1..-3].to_i) do bytes = session.gets[1..-3].to_i argument = session.read(bytes) session.read(2) # Discard \r\n argument end response = yield(*parts) if response.nil? session.shutdown(Socket::SHUT_RDWR) break else session.write(response) session.write("\r\n") end end end end module Helper # Forks the current process and starts a new mock Redis server on # port 6380. # # The server will reply with a `+OK` to all commands, but you can # customize it by providing a hash. For example: # # redis_mock(:ping => lambda { "+PONG" }) do # assert_equal "PONG", Redis.new(:port => 6380).ping # end # def redis_mock(replies = {}) begin pid = fork do trap("TERM") { exit } RedisMock.start do |command, *args| (replies[command.to_sym] || lambda { |*_| "+OK" }).call(*args) end end sleep 1 # Give time for the socket to start listening. yield ensure if pid Process.kill("TERM", pid) Process.wait(pid) end end end end end