LoginSignup
6
3

More than 5 years have passed since last update.

テストでいい感じに一時ディレクトリを作る「rspec-temp_dir」

Posted at

rspec-temp_dirとは?

rspecでいい感じに一時ディレクトリを作るためのgemです

なぜ作ったか?

テストで検証したい内容がメソッドの戻り値だとその戻り値をexpect で検証するだけなのでテストが楽なのですが、ファイルを出力するようなメソッドだとファイルが書き込まれているか検証する必要があります。

テストで作ったファイルを毎回 after で消すとテストコードが肥大化するので、「それなら最初から一時ディレクトリにファイルを書き出してやればファイル消す必要ないのでは?」という発想で作りました。

JUnitの TemporaryFolder にインスパイヤされています。

使い方

describecontext の中に include_context "uses temp dir" を書くとテスト実行時に一時ディレクトリが作られて temp_dirString 版)と temp_dir_pathPathname 版)で取得できるようになります。

サンプルコード

require 'rspec/temp_dir'

describe "uses temp dir" do
  include_context "uses temp dir"

  it "should create temp_dir" do
    expect(Pathname(temp_dir)).to be_exist
  end

  it "can create file in temp_dir" do
    temp_file = "#{temp_dir}/temp.txt"

    File.open(temp_file, "w") do |f|
      f.write("foo")
    end

    expect(File.read(temp_file)).to eq "foo"
  end

  describe "#temp_dir_path" do
    subject{ temp_dir_path }

    it { should be_an_instance_of Pathname }
    it { should be_exist }
  end
end

実装

require を除くとたったこれだけです 1

lib/rspec/temp_dir/uses_temp_dir.rb
RSpec.shared_context "uses temp dir" do
  around do |example|
    Dir.mktmpdir("rspec-") do |dir|
      @temp_dir = dir
      example.run
    end
  end

  attr_reader :temp_dir

  def temp_dir_path
    Pathname(temp_dir)
  end
end

Dir#mktmpdir の「ブロック内から抜けると一時ディレクトリを削除する」という特徴を利用しています。

v0.0.4 -> v1.0.0

アドベントカレンダー執筆に際してv1.0.0にしました。

破壊的な変更は下記です。

RSpec 2系のサポートをやめた

  • さすがにもう誰も2系使っていないよねということでサポートやめた
    • 少なくとも自分の観測範囲では見ていない
  • 2系と3系両方考慮するとコードが汚くなるのでやめたかった
    • 2系だと shared_contextObject に生えていて、 3系だと RSpec に生えているため下記のように書くしかなかった :innocent:
lib/rspec/temp_dir/uses_temp_dir.rb
(RSpec.respond_to?(:shared_context) ? RSpec : Object).shared_context "uses temp dir" do

end

Ruby 1.9系のサポートをやめた

  • json gemが2系でRuby 2系未満を切り捨てて bundle install できなくなったため
  • json gem使っているのはdevelopment dependencyなので「Ruby 1.9系なら json 1系を使う」みたいなTravis CIの設定を書く(もしくは1.9自体Travisでビルドしない)という選択肢もあったけど、積極的にRuby 1.9系をサポートし続ける理由も特に思いつかなかったのでバッサリ spec.required_ruby_version = ">= 2.0.0" を書きました。
6
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3