私はAlbumモデルとChild Pictureモデルを持っており、ファイルアップロードはcarrierwaveによって処理されます。ActionDispatch :: Http :: UploadedFileは統合テスト中に文字列として渡されます
アプリケーションは意図したとおりに動作しますが、アップロードの統合テストを作成しようとすると失敗します。開発ログから
次のように、このための作業パラメータが表示されます。
Parameters: ..., "images"=>[#<ActionDispatch::Http::UploadedFile:0x007f8a42be2c78>...
統合テスト時には、イム次のようにパラメータを取得:
Parameters: ..., "images"=>["#<ActionDispatch::Http::UploadedFile:0x00000004706fd0>"...
あなたが見ることができるようにテストシナリオで#<ActionDispatch::Http::UploadedFile
が文字列(byebugで確認済み)として渡されているため、テストが失敗します。
これをオブジェクトとして渡すにはどうすればよいですか?
統合テストtest_helper.rb
# Upload File (Carrierwave) Ref: http://nicholshayes.co.uk/blog/?p=405
def uploaded_file_object(klass, attribute, file, content_type = 'image/jpeg')
filename = File.basename(file.path)
klass_label = klass.to_s.underscore
ActionDispatch::Http::UploadedFile.new(
tempfile: file,
filename: filename,
head: %Q{Content-Disposition: form-data; name="#{klass_label}[#{attribute}]"; filename="#{filename}"},
type: content_type
)
end
モデルから
require 'test_helper'
class AlbumsCreationTest < ActionDispatch::IntegrationTest
def setup
@user = users(:archer)
@file ||= File.open(File.expand_path(Rails.root + 'test/fixtures/cat1.jpg', __FILE__))
@testfile ||= uploaded_file_object(PicturesUploader, :image, @file)
end
test "should create new album with valid info" do
log_in_as(@user)
assert_difference 'Album.count', 1 do #This assertion fails
post user_albums_path(@user), album: { title: 'test',
description: 'test',
}, images: [@testfile]
end
assert_redirected_to @user
end
end
class Album < ActiveRecord::Base
belongs_to :user
has_many :pictures, dependent: :destroy
accepts_nested_attributes_for :pictures, allow_destroy: true
validates_presence_of :pictures
end
class Picture < ActiveRecord::Base
belongs_to :album
mount_uploader :image, PicturesUploader
validates_integrity_of :image
validates_processing_of :image
validates :image, presence: true,
file_size: { less_than: 10.megabytes }
end
コントローラ
class AlbumsController < ApplicationController
before_action :valid_user, only: [:new, :create, :edit, :update, :destroy]
def create
@album = current_user.albums.build(album_params)
if params[:images]
params[:images].each { |file|
debugger #file.class is String in integration test
@album.pictures.build(image: file)
}
end
if @album.save
# end
flash[:success] = "Album Created!"
redirect_to current_user
else
flash[:alert] = "Something went wrong."
render :new
end
end
private
def album_params
params.require(:album).permit(:user_id, :title, :description, :price,
pictures_attributes: [:id, :image, :image_cache, :_destroy])
end
def valid_user
@user = User.friendly.find(params[:user_id])
redirect_to(root_url) unless @user == current_user
end
end