This is far easier than anybody is making it out to be. I don't mean to demean anybody, as it took me some time to figure this out based on these answers. I'm going to use the same data model to make it easy.
User has one attached "avatar". Let's say you have this users fixture:
# users.yml
fred:
name: Fred
Here's all you need to do:
% mkdir test/fixtures/active_storage
Now, you just put "attachments.yml" and "blobs.yml" in that directory. The "attachment" record will reference the blob as well as the user:
# active_storage/attachments.yml
freds_picture:
name: avatar
record: fred (User)
blob: freds_picture_blob
and
# 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==
service_name: local
The key
is generated like this in code:
ActiveStorage::Blob.generate_unique_secure_token
You can run that in the console to get a key for the above fixture.
Now, that will "work" to have an attached picture. If you need the actual file to be there, first look in config/storage.yml to see what path the files are stored in. By default, it's "tmp/storage". The file above will be stored here:
tmp/storage/aa/bb/aabbWNGW1VrxZ8Eu4zmyw13A
To calculate the checksum, see here:
How is the checksum calculated in the blobs table for rails ActiveStorage
md5_checksum = Digest::MD5.file('tmp/storage/aa/bb/aabbWNGW1VrxZ8Eu4zmyw13A').base64digest
It would be possible to fill in the file size and checksum using erb in the fixture:
byte_size: <%= File.size('tmp/storage/aa/bb/aabbWNGW1VrxZ8Eu4zmyw13A') %>
checksum: <%= Digest::MD5.file('tmp/storage/aa/bb/aabbWNGW1VrxZ8Eu4zmyw13A').base64digest %>
Note that you have to copy the file into the storage directory first.
The storage root directory for the test environment is tmp/storage/
by default, with the remaining path constructed from the first four characters of the key
(i.e. tmp/storage/aa/bb
).