CarrierWaveの画像投稿テストがやっとできた fixture作成とアップロードテスト
長い間避けてたCarrierWave画像投稿のテストをついにやってみる。ドキュメントが英語だったので逃げてました笑
条件
rails 5.1.7
carrierwave 1.2.2
CarrierWaveを設定する
config/initializers/carrierwave.rb CarrierWave.configure do |config| ・ ・ config.root = "/var/www/app" config.cache_dir = "/var/www/app/uploads/tmp" end
app/uploaders/product_picture_uploader.rb class ProductPictureUploader < CarrierWave::Uploader::Base (省略) def store_dir "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" end
テスト用のCarrierwaveに関する設定
test/carrierwave_helper.rb require 'fileutils' # Carrierwave setup and teardown carrierwave_template = Rails.root.join('test','fixtures','files') carrierwave_root = Rails.root.join('test','support','carrierwave') # Carrierwave configuration is set here instead of in initializer CarrierWave.configure do |config| config.root = carrierwave_root config.enable_processing = false config.storage = :file config.cache_dir = Rails.root.join('test','support','carrierwave','carrierwave_cache') end # And copy carrierwave template in #puts "Copying\n #{carrierwave_template.join('uploads').to_s} to\n #{carrierwave_root.to_s}" FileUtils.cp_r carrierwave_template.join('uploads'), carrierwave_root at_exit do #puts "Removing carrierwave test directories:" Dir.glob(carrierwave_root.join('*')).each do |dir| #puts " #{dir}" FileUtils.remove_entry(dir) end end
下記のコードをコピペするだけで設定できます。
github.com
設定内容は、
- CarrierWaveの対象ディレクトリを test/support/carrierwave に変更
- テスト開始時に test/fixtures/files/uploads をコピーして、test/support/carrierwave/uploads を作成
- テスト終了時に test/support/carrierwave 以下のディレクトリを全て削除
になります。
そして、このヘルパーメソッドをtest_helperで使えるようにrequireします
ENV['RAILS_ENV'] ||= 'test' require File.expand_path('../../config/environment', __FILE__) require 'rails/test_help' require 'carrierwave_helper' ← 追加 (省略)
テストデータ作成
$ tree ${RAILS_ROOT}/test/ test/ ## 省略 ## ├── fixtures │ ├── files │ │ └── uploads │ │ └── product │ │ ├── 1 │ │ │ └── product1.jpg │ │ └── 2 │ │ └── product2.jpg │ │ │ └── products.yml ├── support │ └── carrierwave ├── carrierwave_helper.rb └── test_helper.rb
products.ymlでディレクトリにある画像の名前を指定する
products.yml shampoo: name: "good shampoo" price: "3000" description: "very good shampoo" picture: "product1.jpg" Treatment: name: "lovely treatment" price: "2000" description: "very good shampoo" picture: "product2.jpg"
最後にアップロードテスト
内容な人それぞれですが、こんな感じでかけばアップロードが成功しているかをテストできます。
test "should create product with logged in" do log_in_as(@user) get products_path assert_difference 'Product.count',1 do post products_path, params: { product:{ name: 'so good shampoo', price: '2000', description: 'so good shampoo', picture: fixture_file_upload(Rails.root.join('test','fixtures','files', 'product1.jpg')) }} end assert_redirected_to product_url(Product.last) end
この例だとログインして新規の商品を作成し、その商品ページに飛べるかをテストしています。