解決したいこと
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できるのか?(調査中)
調査次第追記します。
参考元
こちらの記事を参考にさせていただきました!