Edited at

Thor で作ったサブコマンドを Rspec でテストする

More than 1 year has passed since last update.

Ruby はあんま経験がなくてハマったのでメモ。

Thor を使って Git 風の CLI ツールを作ってるんですが、そのテストでコマンドラインオプションとかパラメータを渡す方法がよくわかんなくて、ぐぐって出てくる方法もなんだかうまくいかなくて、テストでハマってどうすんのよ状態だったんですが、本家のリポジトリにやまほどサンプルがあった。

https://github.com/erikhuda/thor

まず spec_helper.rb に以下のようなメソッドを追加。

RSpec.configure do |config|

...
...

def capture(stream)
begin
stream = stream.to_s
eval "$#{stream} = StringIO.new"
yield
result = eval("$#{stream}").string
ensure
eval("$#{stream} = #{stream.upcase}")
end

result
end
end

このメソッドは標準出力をキャプチャして変数に放り込むためのメソッドです。

Thor のリポジトリから丸パクリしました。

https://github.com/erikhuda/thor/blob/master/spec/helper.rb

次にテストコードは以下のような感じ。

require 'spec_helper'

require 'oreore/cli'
require "json"

describe Oreore::Command do

it "Tests for the oreore cli" do
output = capture(:stdout) { Oreore::Command.start( %w[record get --app=5] ) }
expect( JSON.parse( output ).count ).to be > 0
end

end

この場合、oreore record get --app=5 みたいなコマンドを想定したテストをしています。

$ bundle exec rspec

で合格。すっきりした。

あと、コマンドによっては標準エラーを出して死んでもらうケースもあって、そういう場合は以下のような感じ。

  it "Incorrect parameters" do

expect{
capture(:stderr) {
Oreore::Command.start( [
"record",
"get"
] )
}
}.to raise_error( SystemExit )
end

expect の後のカッコが丸カッコから波カッコにかわるのか。。。