解決したいこと
RSpecでテストを実行するとき、実装に含まれているsleepメソッドで待機時間が発生し、テストの実行時間が増大してしまうので対処したい。
具体例
Sample#testについてテストする例。
lib/sample.rb
class Sample
def test
sleep 10
end
end
sleepメソッドはKerenlクラスのメソッドなので、Kernelクラスでmockしようとしてみる。
spec/lib/sample_spec.rb
require_relative '../../lib/sample'
describe Sample do
it 'not to sleep' do
allow(Kernel).to receive(:sleep)
expect { sample.test }.to_not raise_error
end
end
しかし、テストを実行してみると、Finished in 10.01 secondsと時間がかかる。
$ bundle exec rspec spec/lib/sample_spec.rb
.
Finished in 10.01 seconds (files took 0.06606 seconds to load)
1 example, 0 failures
解決方法
Sampleのインスタンスに対してallowで振る舞いを教える。
spec/lib/sample_spec.rb
require_relative '../../lib/sample'
describe Sample do
it 'not to sleep' do
sample = Sample.new
allow(sample).to receive(:sleep)
expect { sample.test }.to_not raise_error
end
end
今度はテストを実行してみると、inished in 0.00965 secondsとすぐに完了した。
$ bundle exec rspec spec/lib/sample_spec.rb
.
Finished in 0.00965 seconds (files took 0.05652 seconds to load)
1 example, 0 failures
sleepメソッドの振る舞いを上書きする
完全にはsleepさせたくない場合に、and_wrap_originalで振る舞いを変更できる。
spec/lib/sample_spec.rb
require_relative '../../lib/sample'
describe Object do
it 'not to sleep' do
sample = Sample.new
allow(sample).to receive(:sleep).and_wrap_original { |method, _| method.call(0.5) }
expect { sample.test }.to_not raise_error
end
end
上記の例では、sleepメソッドに渡す引数が何であっても0.5秒待つようになる。実行してみると、約0.5秒かかっていることがわかる。
% bundle exec rspec spec/lib/sample_spec.rb
.
Finished in 0.50638 seconds (files took 0.05306 seconds to load)
1 example, 0 failures
なぜこれでmockできるのか?(調査中)
調査次第追記します。
参考元
こちらの記事を参考にさせていただきました!