Railsテスト。アクティブストレージのみの基本モデルがあります:
class User < ApplicationRecord
has_one_attached :avatar
end
私はそれをフィクスチャにしようとしていますが、運がありません(私はそこに画像を持っています):
# users.yml
one:
avatar: <%= File.open Rails.root.join('test', 'files', 'image.png').to_s %>
フィクスチャを介してアバターファイルを適切に添付するにはどうすればよいですか?
モデルユーザーのテストがあるとしましょう。デフォルトはUserTest#test_the_truth
です。
Rails test test/models/user_test.rb
テスト中にエラーErrno::ENOENT: No such file or directory @ rb_sysopen
が発生したと思います。パスにエラーがあるため、'fixtures'
を追加する必要があります。次のようになります。
# users.yml
one:
name: 'Jim Kirk'
avatar: <%= File.open Rails.root.join('test', 'fixtures', 'files', 'image.png').to_s %>
しかし今、あなたはこのエラーを持っているはずです:ActiveRecord::Fixture::FixtureError: table "users" has no column named "avatar".
ActiveStorageはactive_storage_attachments
とactive_storage_blobs
の2つのテーブルを使用して機能するため、これは正しいです。
したがって、users.yml
からアバター列を削除し、2つの新しいファイルを追加する必要があります。
# active_storage_attachments.yml
one:
name: 'avatar'
record_type: 'User'
record_id: 1
blob_id: 1
そして
# active_storage_blobs.yml
one:
id: 1
key: '12345678'
filename: 'file.png'
content_type: 'image/png'
metadata: nil
byte_size: 2000
checksum: "123456789012345678901234"
また、App/models
に、ActiveStorageが機能するために必要でない場合でもを追加します。
# active_storage_attachment.rb
class ActiveStorageAttachment < ApplicationRecord
end
そして
# active_storage_blob.rb
class ActiveStorageBlob < ApplicationRecord
end
その後、UserTest#test_the_truth
は成功します。
しかし、より良い取り除くactive_storage_attachment.rb
とactive_storage_blob.rb
そして別の方法でテストしてください。
アタッチメントが機能しているかどうかをテストするには、コントローラーをより適切にテストします、たとえば、このコードをtest/controllers/users_controller_test.rb
に追加します。
require 'test_helper'
class UserControllerTest < ActionController::TestCase
def setup
@controller = UsersController.new
end
test "create user with avatar" do
user_name = 'fake_name'
avatar_image = fixture_file_upload(Rails.root.join('test', 'fixtures', 'files', 'avatar.png'),'image/png')
post :create, params: {user: {name: user_name, avatar: avatar_image}}
end
end
フォルダtmp/storage
を確認してください。空になっているはずです。
次のコマンドでテストを開始します:Rails test test/controllers/users_controller_test.rb
成功するはずです。tmp/storage
をもう一度チェックすると、テストによって生成されたいくつかのフォルダーとファイルが見つかります。
コメントの後に編集:User
モデルでコールバックをテストする必要がある場合、これは機能するはずです。
# Rails test test/models/user_test.rb
require 'test_helper'
class UserTest < ActiveSupport::TestCase
test "should have avatar attached" do
u = User.new
u.name = 'Jim Kirk'
file = Rails.root.join('test', 'fixtures', 'files', 'image.png')
u.avatar.attach(io: File.open(file), filename: 'image.png') # attach the avatar, remove this if it is done with the callback
assert u.valid?
assert u.avatar.attached? # checks if the avatar is attached
end
end
あなたのコールバックはわかりませんが、これがあなたにいくつかのヒントを与えることを願っています。
私が拡張したい唯一の答えについて、IS04による失われたコメントがあります。
私はしばらくの間これをしようとして立ち往生しました、そしてiGianの答えに従うことは私のために働きました。しかし、私のチームは私のPRをレビューし、ActiveStorage自身のモデル(つまり、ActiveStorage::Attachment
とActiveStorage::Blob
)に非常に近い名前の新しいモデルを導入する理由を尋ねました。
その後、フィクスチャをactive_storage_attachments.yml
からactive_storage/attachments.yml
に移動するだけでよいことに気付きました。
追加の調査で理解しなければならなかった他の部分は、自動生成されたIDでこれらのフィクスチャを使用する方法でした。このようにActiveRecord::FixtureSet.identify
を使用してこれを行いました:
attachment_identifier:
name: "attachment_name"
record_type: "MyRecordClass"
record_id: <%= ActiveRecord::FixtureSet.identify(:my_record_identifier) %>
blob_id: <%= ActiveRecord::FixtureSet.identify(:blob) %>
created_at: <%= Time.zone.now %>
これは、誰もが考えているよりもはるかに簡単です。これらの答えに基づいてこれを理解するのに時間がかかったので、私は誰かを侮辱するつもりはありません。簡単にするために同じデータモデルを使用します。
ユーザーには「アバター」が1つ添付されています。このユーザーフィクスチャがあるとしましょう:
# users.yml
one:
name: Fred
これがあなたがする必要があるすべてです:
% mkdir test/fixtures/active_storage
これで、「attachments.yml」と「blobs.yml」をそのディレクトリに配置するだけです。 「添付ファイル」レコードは、ユーザーだけでなくblobも参照します。
# active_storage/attachments.yml
freds_picture:
name: avatar
record: fred (User)
blob: freds_picture_blob
そして
# active_storage/blobs.yml
freds_picture_blob:
key: aabbWNGW1VrxZ8Eu4zmyw13A
filename: fred.jpg
content_type: image/jpeg
metadata: '{"identified":true,"analyzed":true}'
byte_size: 1000
checksum: fdUivZUf74Y6pjAiemuvlg==
さて、それは添付の写真を持つために「機能」します。実際のファイルが必要な場合は、最初にconfig/storage.ymlを調べて、ファイルが保存されているパスを確認します。デフォルトでは、「tmp/storage」です。上記のファイルはここに保存されます:
tmp/storage/aa/bb/aabbWNGW1VrxZ8Eu4zmyw13A
チェックサムを計算するには、次を参照してください。
Rails ActiveStorage のblobテーブルでチェックサムはどのように計算されますか
md5_checksum = Digest::MD5.file('tmp/storage/aa/bb/aabbWNGW1VrxZ8Eu4zmyw13A').base64digest
フィクスチャでerbを使用して、ファイルサイズとチェックサムを入力することができます。
byte_size: <%= File.size('tmp/storage/aa/bb/aabbWNGW1VrxZ8Eu4zmyw13A') %>
checksum: <%= Digest::MD5.file('tmp/storage/aa/bb/aabbWNGW1VrxZ8Eu4zmyw13A').base64digest %>
最初にファイルをストレージディレクトリにコピーする必要があることに注意してください。