rspec+glint

2014-03-02T00:00:00+00:00 rspec Ruby

以前にrspecとspawnっていうのをやったけど、それっぽい事を実現するのにglintっていうのがあるらしいのでやってみた

lib/sample.rb

require "mongo"

class Sample
  def self.get
    client = mongo()
    db = client.db("sample")
    coll = db.collection("samples")

    coll.find_one
  end

  def self.mongo
    Mongo::MongoClient.new(
      Mongo::MongoClient::DEFAULT_HOST,
      Mongo::MongoClient::DEFAULT_PORT
    )
  end
  private_class_method :mongo

end

前回のとはちょっとだけ修正。MongoDBなクライアントインスタンスをメソッドとして出しておいた。今回はこれをmockする事でテスト時に起動したMongoDBなクライアントインスタンスに差し替える事で実現する

spec/spec_helper.rb

公式にあるmemcachedなサンプルなのではspec_helperでのglintによるサーバーの起動処理等に関しては別のスクリプト上で行い、Glient::Server.infoっていうプロパティ的なのを使ってる模様だけど今回はパスするので気になる場合はそちらを参照すりゃよろし

RSpec.configure do |config|
  config.treat_symbols_as_metadata_keys_with_true_values = true
  config.run_all_when_everything_filtered = true
  config.filter_run :focus
  config.order = "random"
end

require "glint"
require "mongo"

server = Glint::Server.new do |port|
  exec "mongod",
    "--dbpath", "/tmp/mongo",
    "--logpath", "/dev/null",
    "--port", port.to_s
  exit 0
end
server.on_stopped = ->(s) { puts "mongodb stopped" }
server.start

shared_context "mongodb" do
  let(:client) do
    Mongo::MongoClient.new("localhost", server.port)
  end
end

※別途事前に/tmp/mongoを作っておいてそこにMongoDBなデータを事前に突っ込んでしておく

spec/sample_spec.rb

require "spec_helper"
require "sample"

describe Sample do
  include_context "mongodb"

  it {
    Sample.stub(:mongo).and_return(client)
    entry = Sample.get
    expect(entry).not_to be_nil
  }
end

ってな感じでやって、実行すると

all output going to: /dev/null
Run options: include {:focus=>true}

All examples were filtered out; ignoring {:focus=>true}
.

Finished in 0.0148 seconds
1 example, 0 failures

Randomized with seed 55319

mongodb stopped

そのPCにMongoDBを起動してない(デフォルトポートとかで)場合とかで、mockによるMongo::MongoClientの差し替えをしない場合とかだとテストが失敗する。

っていう感じで、サーバープロセスをテスト開始時とかに起動してそのコネクションを利用したりするような場合のテスト手法を用いる場合はこれを使えばいいっぽい

余談として、glintはRuby版だけじゃなくてnode.js版もあるらしい

mocha-phantomjsでlocalToRemoteUrlAccessEnabled gradle warでJSをバンドルさせる