rails で redis な test

Redis の instance は

config/initializers/redis.rb のような所で

uri = URI.parse(ENV["REDISTOGO_URL"])
$redis = Redis.new( :host => uri.host, :port => uri.port, :password => uri.password )

で作ってるとして

RSpec and Resque · resque/resque Wiki · GitHub を参考にした。

ただ、

config.before(:suite) だと複数のテストで1回しか初期化されないので config.before(:all) の方がいいと思った。

で、ここが走ってる時は config/initializers/redis.rb が読み込まれているので、test の所で再代入するほうが良いと思った。
後は並列で走らせたことも考えると、port, pid, cache_dir それぞれ別のものを使うと良いと思った。

port に関しては
使ってないポートを取得する #Ruby - Qiita [キータ] を参考にした。

上のを踏まえて下の感じで動かすことにしたのであった。

  config.before(:all) do

    @redis_pid = Tempfile.new(["redis-test", ".pid"])
    @redis_cache_dir = Dir.mktmpdir

    # http://qiita.com/items/bf47e254d662af1294d8
    s = TCPServer.open(0)
    redis_port = s.addr[1]
    s.close

    redis_options = {
      "daemonize"     => 'yes',
      "pidfile"       => @redis_pid.path,
      "port"          => redis_port,
      "timeout"       => 300,
      "save 900"      => 1,
      "save 300"      => 1,
      "save 60"       => 10000,
      "dbfilename"    => "dump.rdb",
      "dir"           => @redis_cache_dir,
      "loglevel"      => "debug",
      "logfile"       => "stdout",
      "databases"     => 16
    }.map { |k, v| "#{k} #{v}" }.join("\n")

    $redis = Redis.new( :host => "localhost", :port => redis_port )
    `echo '#{redis_options}' | redis-server -`
  end

  config.after(:all) do
    %x{
      cat #{@redis_pid.path} | xargs kill -QUIT
    }
    @redis_pid.unlink
    FileUtils.remove_dir @redis_cache_dir, true
  end

perl でこういうことをやる場合は、typester/Test-RedisServer · GitHub を使うと良い。