RSpecで終了ステータスをテストする
RSpecでアプリケーションの終了ステータスをテストしたい時があります。Rubyアプリケーションで、exit(Kernel::exit, Process::exit)
が呼ばれるとSystemExit
例外が発生します。riからexit
の挙動のコードを抜粋すると、
begin exit puts "never get here" rescue SystemExit puts "rescued a SystemExit exeption" end puts "after begin block"
ということで、例外を補足すれば書けるので
expect {...}.to raise_error()
で実現できますが、ここは一歩進んでCustom Matcherを作成してみましょう。
RSpec::Matchers.define :exit_with_code do |code| actual = nil match do |block| begin block.call rescue SystemExit => e actual = e.status end actual && actual == code end failure_message_for_should do |block| "expected block to call exit(#{code}) but exit" + (actual.nil? ? " not called" : "(#{actual}) was called" ) end failure_message_for_should_not do |block| "expected block not to call exit(#{code})" end description do "expect block to call exit(#{code})" end end
spec_helper.rb等に定義しておくことで、
describe LocalPort do context "executed in no args" do it "should show usage and exit status is 1" do expect { LocalPort.parse_args([]) }.to exit_with_code(1) end end end
と使えます。