web-dev-qa-db-fra.com

Comment utiliser Factory Girl pour générer un attachement de trombone?

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.

118
Laz

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.

84
DanS

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
47
Neal

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
37
Rick Quantz

J'ai utilisé le code dans le Gist ci-dessous:

Rails 2

http://Gist.github.com/162881

Rails 3

https://Gist.github.com/313121

25
deb
file { File.new(Rails.root.join('spec', 'fixtures', 'filename.png')) }
12
Matthew Deiters

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'))
   ] 
}
4
britt

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
}
0
Aleks