コンユウメモ @kon_yu

作ったガラクタとか、旅行とかの話

parperclipでファイルアップロードをRspecでテスト w/ factory_girl

動作確認環境

準備 設定ファイル修正rails_helper.rb

rails_helpler.rbに、ファイルアップロードのモック(でいいのかな?)する機能のある fixture_file_uploadを呼び出せるように、ラブラリを読み込むように追記する

また、ファイルのアップロード自体をテストするためのものと、 FactoriGirlで作ったフィクスチャでファイルがアップロードされたものを作る場合では、定義の仕方が違うので注意が必要だ

※ここに書いておかないと、factory_girlのファイルや、specファイルに include ActionDispatch::TestProcessをいちいち追記しなければならず、 追記を忘れてしまい動作がうまい行かない原因に気づきにくい

追記箇所は以下のようにRSpec.configureのブロック内に追記する

RSpec.configure do |config|
  ...
  ..
  # paperclip file uploadテスト用
  # rspec内で、ファイルアップロードのテストに使用する
  config.include ActionDispatch::TestProcess

  # factoryGirl内での呼び出し
  FactoryGirl::SyntaxRunner.class_eval do
    include ActionDispatch::TestProcess
  end
  
  # fixtureのパス指定
  # ファイルアップロードテストする際のアップするファイルを指定するパスをfixtures以下から省略して指定できる
  config.fixture_path = "#{::Rails.root}/spec/fixtures"

end

ファイルアップロードのテスト

アップロード対象のファイルを置く

fixture_pathを通してある/spec/fixturesの下にアップロード対象のファイルを置く 今回の説明では/spec/fixtures/voice/voice01.mp3を設置する

※ ダミーのテキストファイルの拡張子を変えただけのファイルだとファイルのアップロードできませんと怒られるので、小さめのアップロード対象のファイルを用意してあげるのがよろしいかと

アップロードするメソッドの呼び出し方

# 呼び出し方
fixture_file_upload("相対パスのファイル名", "mime_type"))

# mp3の場合
fixture_file_upload("voice/voice01.mp3", "audio/mp3"))

# pngファイルの場合
fixture_file_upload("image/image01.png", 'image/png') 
    

具体的なRspecコード例

describe "#update a and file upload" do
  it "can upload with update_attributes" do
   # sound モデルを更新してファイルをアップロードする
    sound.update_attributes(voice: fixture_file_upload("voice/voice01.mp3", "audio/mp3"))

    sound.reload
    # paperclipで生成されたファイル名を格納したカラムに値が入っていることを確認
    expect(sound.voice_file_name).not_to be_nil
 end
end

Factory_girlのフィクスチャでファイルをアップロード済みのモデルと定義する場合

factory_girlの定義

factory :sound do
  content "original"
  xxx_id 1
  trait(:recorded) do
    # factory_girlのファイルではfixture_pathを見てくれないので頭からパスを定義して上げる必要があった。
    voice { fixture_file_upload("#{::Rails.root}/spec/fixtures/voice/voice01.mp3", "audio/mp3") }
  end
end 

※ factori_girlのtraitは大変便利なので使うことを推奨する

specファイルで呼び出し例

let(:sound) { FactoryGirl.create(:sound, :recorded) }
 

ref:http://apidock.com/rails/ActionController/TestProcess/fixture_file_upload