Posted at

FileUtils::DryRunを使ってテストする

More than 1 year has passed since last update.


TL;DR

remove_constconst_set(or 定数代入)を使ってFileUtilsFileUtils::DryRunにすり替えて、stderrに吐き出されるメッセージを確かめる。


準備

spec_helpr.rbやモックを行う場所に以下のコードを書きます。

Object.class_eval do

RealFileUtils = FileUtils
remove_const(:FileUtils)
FileUtils = RealFileUtils::DryRun
end

FileUtilsFileUtils::DryRunに差し替えています。


サンプル


実装コード

今回は以下のコードをテストしてみましょう。


sample.rb

class Sample

def copy_gemfile
FileUtils.copy("Gemfile", "CopyGemfile")
end
end

FileUtils.copyを使ってGemfileというファイルをCopyGemfileにコピーしています。


テストコード


sample_spec.rb

RSpec.describe Sample do

it do
expect {
Sample.new.copy_gemfile()
}.to output("cp Gemfile CopyGemfile\n").to_stderr_from_any_process
end
end

FileUtils::DryRunのソースを読むとstderrに出力されていることが分かったのでそのようなテストを書きます。

to_stderr_from_any_processがポイントです。to_stderrではFileUtils::DryRunの出力を捕捉できません(原因はよく分かってないです)。

FileUtils::DryRunにすり替えられているため、テストを走らせてもファイルのコピーは行われておらず、代わりにcopy Gemfile CopyGemfile\nというメッセージがstderrに出力されます。出力には最後に改行が入るため、注意です。


参考

FileUtilsFileUtils::DryRunに差し替える方法はFakeFSの以下の実装を参考にしました。


https://github.com/fakefs/fakefs/blob/master/lib/fakefs/base.rb


FakeFSの方ではremove_constconst_setを使っているようです。今回const_setを使わず代入を用いたことに深い意味はありません。

濫用はできませんが、応用が効きそうな手法ですね。