こういうテストがあるとする
spec/my_spec.rb
require 'spec_helper'
require 'rack-timeout'
class Klass
end
describe 'Rack::Timeout::RequestTimeoutException' do
it 'bad' do
expect(Klass).to receive(:new).and_raise(Rack::Timeout::RequestTimeoutException)
expect {
Klass.new
}.to raise_error(Rack::Timeout::RequestTimeoutException)
end
it 'good' do
expect(Klass).to receive(:new).and_raise(Rack::Timeout::RequestTimeoutException.new( {} ))
expect {
Klass.new
}.to raise_error(Rack::Timeout::RequestTimeoutException)
end
end
実行するとこうなる
$ rake
Rack::Timeout::RequestTimeoutException
bad (FAILED - 1)
good
Failures:
1) Rack::Timeout::RequestTimeoutException bad
Failure/Error:
expect {
Klass.new
}.to raise_error(Rack::Timeout::RequestTimeoutException)
expected Rack::Timeout::RequestTimeoutException, got #<ArgumentError: wrong number of arguments (given 0, expected 1)> with backtrace:
# ./spec/my_spec.rb:11:in `block (3 levels) in <top (required)>'
# ./spec/my_spec.rb:10:in `block (2 levels) in <top (required)>'
# ./spec/my_spec.rb:10:in `block (2 levels) in <top (required)>'
Finished in 0.0397 seconds (files took 0.28993 seconds to load)
2 examples, 1 failure
Failed examples:
rspec ./spec/my_spec.rb:8 # Rack::Timeout::RequestTimeoutException bad
Rack::Timeout::RequestTimeoutException#initialize
は引数を一つとるが and_raise
に例外クラスそのものを渡すと new するとき引数を渡してくれないので ArgumentError
がでてしまう。
https://github.com/heroku/rack-timeout/blob/bd7b37117867e224ed68c8cc9eed6256203ab169/lib/rack/timeout/core.rb#L12-L17
適当な引数を渡して作ったインスタンスを and_raise
に渡せば、意図した通りに動く。
参考(っていうかこのブログ記事のほうがより詳しい)
https://tnakamura.hatenablog.com/entry/2015/02/02/rspec_mocks_and_raise