J'ai le modèle Person qui contient de nombreuses images, où images comporte un champ de pièce jointe appelé un trombone appelé data, une version abrégée affichée ci-dessous:
class Person
has_many :images
...
end
class Image
has_attached_file :data
belongs_to :person
...
end
La personne doit avoir au moins une image associée.
Lorsque j'utilise FactoryGirl, mon code s'apparente à celui-ci:
Factory.define :image do |a|
a.data { File.new(File.join(Rails.root, 'features', 'support', 'file.png')) }
a.association :person
end
Factory.define :person do |p|
p.first_name 'Keyzer'
p.last_name 'Soze'
p.after_create do |person|
person.assets = [Factory.build(:image, :person => person)]
end
# p.images {|images| [images.association(:image)]}
end
(NB: j’ai aussi essayé d’essayer avec le code commenté ci-dessus).
Aucun fichier ou répertoire de ce type - /tmp/stream,9887,0.png (Errno :: ENOENT)
...
Parfois, les tests fonctionnent avec succès.
Quelqu'un peut-il me dire quel est le problème que j'ai ici ou comment ils utilisent FactoryGirl et Paperclip ensemble pour réaliser quelque chose comme ce que j'essaie de réaliser?
J'utilise Rails 3.
Vous pouvez utiliser fixture_file_upload
include ActionDispatch::TestProcess
dans votre assistant de test, voici un exemple d'usine:
include ActionDispatch::TestProcess
FactoryBot.define do
factory :user do
avatar { fixture_file_upload(Rails.root.join('spec', 'photos', 'test.png'), 'image/png') }
end
end
Dans l'exemple ci-dessus, spec/photos/test.png
doit exister dans le répertoire racine de votre application avant d'exécuter vos tests.
Notez que FactoryBot
est un nouveau nom pour FactoryGirl
.
Nouvelle syntaxe FG et pas d'inclusions nécessaires
factory :user do
avatar { File.new(Rails.root.join('app', 'assets', 'images', 'Rails.png')) }
end
ou, mieux encore,
factory :user do
avatar { File.new("#{Rails.root}/spec/support/fixtures/image.jpg") }
end
Desmond Bowe à Pivotal Labs suggère d'éviter les fixture_file_upload en raison de problèmes de fuite de mémoire. Au lieu de cela, vous devez définir les champs Paperclip directement dans votre usine:
factory :attachment do
supporting_documentation_file_name { 'test.pdf' }
supporting_documentation_content_type { 'application/pdf' }
supporting_documentation_file_size { 1024 }
# ...
end
J'ai utilisé le code dans le Gist ci-dessous:
Rails 2
Rails 3
file { File.new(Rails.root.join('spec', 'fixtures', 'filename.png')) }
Essayez d'utiliser ActionController :: TestUploadedFile. Vous pouvez simplement définir la propriété de fichier sur une instance de TestUploadedFile et Paperclip devrait s'occuper du reste. Par exemple
valid_file = File.new(File.join(Rails.root, 'features', 'support', 'file.png'))
p.images {
[
ActionController::TestUploadedFile.new(valid_file, Mime::Type.new('application/png'))
]
}
Les réponses ci-dessus dans certains cas peuvent aider, et celle-ci m'a effectivement aidé dans l'une de mes situations, mais lorsque vous utilisiez un Carrierwave, la solution précédente de cette question ne fonctionnait pas cette fois.
PREMIÈRE APPROCHE:
Pour moi, l'ajout d'un after :create
a résolu le problème pour moi comme ceci:
after :create do |b|
b.update_column(:video_file, File.join(Rails.root, 'spec', 'fixtures', 'sample.mp4'))
end
La définition d'un fichier vidéo en ligne tel que video_file { File.new("#{Rails.root}/spec/fixtures/sample.mp4") }
n'a pas fonctionné et signalait des erreurs.
DEUXIEME APPROCHE:
Définissez une usine comme ceci (remplacez personal_file
par le nom de votre pièce jointe):
FactoryGirl.define do
factory :contact do
personal_file { File.new("#{Rails.root}/spec/fixtures/personal_files/my_test_file.csv") }
personal_file_content_type 'text/csv'
end
end
Et ajoutez ces lignes auconfig/environemnts/test.rb
:
config.Paperclip_defaults = {
url: "#{Rails.root}/spec/fixtures/:attachment/:filename",
use_timestamp: false
}