另一种方法是为 yml 定义属性值并准备静态文件,这样我们就可以在测试期间通过 fixture_file_upload 方法即时使用它而无需上传文件(= 节省 CPU 资源)。
1) 假设 Music 模型有如下音频回形针:
class Music < ActiveRecord::Base
has_attached_file :audio
...
end
2) 仅在 config/environments/test.rb 定义音频存储目录用于测试:
MyApp::Application.configure do
Paperclip::Attachment.default_options[:path] = ':rails_root/test/data/paperclip/:class/:attachment/:id_partition/:filename'
...
end
(例如,音频文件“sound_of_music.mp3”将存储在 test/data/paperclip/musics/audios/111/222/333/sound_of_music.mp3 下,其中 111222333 是音乐记录 ID,111/222/333是上面 2) 中定义的 id_partiion 部分。)
(注意:上面对测试的定义会影响开发/生产存储路径(我不知道为什么?)所以我需要在 config/initializers/paperclip.rb 中重新定义 dev & prod 的另一个路径:)
if Rails.env != 'test'
Paperclip::Attachment.default_options[:path] = 'mount_prefix_for_your_app/:rails_env/:class/:attachment/:id_partition/:filename'
end
3) 将 test/fixtures/musics.yml 写为:
music01:
title: 'sound of music'
audio_file_name: sound_of_music.mp3
...
4) 存储实际的 mp3。假设通过 rails-console 从 /tmp/sound_of_music.mp3 上传到上面 2) 中定义的回形针存储:
$ RAILS_ENV=test bundle exec rails console
> include ActionDispatch::TestProcess
> m = Music.find_by_title('sound of music')
> m.audio = fixture_file_upload("/tmp/sound_of_music.mp3", "audio/x-mpeg")
> m.save!
以上步骤 1)..4) 是运行测试前的准备工作。
5) 现在,我们可以在单元测试(或 rails-4 的模型测试)中使用它:
class MusicTest < ActiveSupport::TestCase
...
m = musics(:music01)
assert File.exist?(m.audio.path)
...