Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 67 lines (55 sloc) 1.482 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
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

        session.read(2) # Discard \r\n

        response = yield(*parts)

        if response.nil?
          session.shutdown
          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
Something went wrong with that request. Please try again.