2010-07-20 9 views
117

Ich habe Modell Person, die viele Bilder hat, wo Bilder eine Büroklammer Befestigungsfeld haben Daten genannt, eine gekürzte Version unten angezeigt:Wie verwende ich Factory Girl, um eine Büroklammeranlage zu erstellen?

class Person 
    has_many :images 
    ... 
end 

class Image 
    has_attached_file :data 
    belongs_to :person 
    ... 
end 

Person ist erforderlich, mindestens ein Bild, um es angebracht zu haben.

Wenn factory mit, ich habe Code ähnlich dem folgenden:

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 Ich habe auch den Code versucht, oben auf Kommentar auch versucht wurde) Die meiste Zeit, wenn ich Gurke Funktionen laufen, ich erhalten einen Fehler ähnlich dem folgenden:

keine solche Datei oder das Verzeichnis - /tmp/stream,9887,0.png (Errno :: ENOENT)

...

Manchmal werden die Tests erfolgreich ausgeführt.

Kann mir jemand sagen, was das Problem ist, das ich hier habe oder wie sie FactoryGirl und Paperclip zusammen verwenden, um etwas zu erreichen, was ich erreichen will?

Ich bin mit Rails 3.

+2

abstimmen auf Frage nur für die Verwendung von Keyzer Soze, wie Sie Name testen! – Breno

+0

Was @Breno sagte ... –

+0

Wenn ich dies tue ... Fotos jedes Mal, wenn ich die Testsuite laufen lassen generiert und in den öffentlichen/System-Ordner platziert. Die Fotos werden nicht zerstört, nachdem die Testsuite ausgeführt wurde. Hat das jemand anderes bemerkt? – Jwan622

Antwort

4

Versuchen Action :: TestUploadedFile verwenden. Sie können einfach die Dateieigenschaft auf eine Instanz von TestUploadedFile setzen, und die Büroklammer sollte sich um den Rest kümmern. Zum Beispiel

valid_file = File.new(File.join(Rails.root, 'features', 'support', 'file.png')) 
p.images { 
    [ 
    ActionController::TestUploadedFile.new(valid_file, Mime::Type.new('application/png')) 
    ] 
} 
-1

Was genau testen Sie? Diese Büroklammer wird die Datei erfolgreich anhängen? Das scheint wirklich ein Test zu sein, den Büroklammer behandeln sollte, nicht Ihre Anwendung.

Haben Sie

versucht
a.data { File.join(Rails.root, 'features', 'support', 'file.png') } 

Wir verwenden Maschinist statt factory_girl und haben nur Dinge verwendet wie

Image.blueprint do 
    image { RAILS_ROOT + 'spec/fixtures/images/001.jpg' } 
end 

Obwohl, sind wir nicht wirklich viel zu testen, wenn wir dies tun, in der Regel wir nur möchte ein gültiges Image Objekt haben.

+0

Ich habe Modelle, die eine gültige Zuordnung zu einem Paperclip-fähigen Modell erfordern, das selbst einen gültigen Anhang hat. – Eric

25

Ich habe mit dem Code im Kern unter:

Rails 2

http://gist.github.com/162881

Rails 3

https://gist.github.com/313121

+1

Ich frage mich nur die gleichen Dinge und das funktioniert wunderbar. Vielen Dank. Ich lege es in einen Initialisierer. – Todd

+3

Es wurde ein "stack_level_too_deep" -Fehler beim Rails 3-Snippet festgestellt. – dhulihan

+1

Etwas zu beachten: Der obige Text verwendet die ältere FactoryGirl-Syntax. DanS Antwort verwendet die neue Syntax. –

11
file { File.new(Rails.root.join('spec', 'fixtures', 'filename.png')) } 
+0

Dies ist die einfachste funktionale Lösung. – superluminary

82

Sie fixture_file_upload können

include ActionDispatch::TestProcess in Ihrem Test Helfer, hier ist ein Beispiel Werk:

factory :user do 
    avatar { fixture_file_upload(Rails.root.join('spec', 'photos', 'test.png'), 'image/png') } 
end 

In dem obigen Beispiel spec/photos/test.png muss in Ihren Anwendungen Stammverzeichnis vorhanden ist, bevor die Tests ausgeführt werden.

+2

Diese Antwort ist völlig richtig, aber es kann klarer sein zu sagen, dass die TestProcess-Funktion in der Factory enthalten sein muss und nicht einfach in Ihrem spec_helper. –

+2

Danke für die Klarstellung, Andrew. Sie müssen möglicherweise auch "include ActionDispatch :: TestProcess" vor dem FactoryGirl.define-Block platzieren (was nicht in diesem Sinne passiert: https://gist.github.com/313121). – Sam

+3

Auch die '{}' sind erforderlich. Es bricht ohne es – Edmund

44

Neuere FG Syntax und nicht enthält notwendige

factory :user do 
    avatar { File.new(Rails.root.join('app', 'assets', 'images', 'rails.png')) } 
end 

oder, noch besser,

factory :user do 
    avatar { File.new("#{Rails.root}/spec/support/fixtures/image.jpg") } 
end 
+2

Ich mag es, aber bedenken Sie, dass Schienen 4 app/assets/images/rails.png entfernt, so dass Sie diese Änderung berücksichtigen müssen :) – stephenmurdoch

+0

Das funktioniert, aber leider werden die Bilder in/tmp – pmontrasio

37

Desmond Bowe über bei Pivotal Labs suggests avoiding fixture_file_upload aufgrund Speicherleck Probleme. Stattdessen sollten Sie die Büroklammer Felder direkt in Ihrem Werk eingestellt:

factory :attachment do 
    supporting_documentation_file_name { 'test.pdf' } 
    supporting_documentation_content_type { 'application/pdf' } 
    supporting_documentation_file_size { 1024 } 
    # ... 
end 
+0

Works geladen für mich. Auch einfach genug, um keine vorhandene Datei im Spezifikations-/Testordner zu benötigen. – bibstha

+0

Einfach peezie, zitrone squeezie !!!! –

+1

Neben der Vermeidung von Speicherlecks werden auf diese Weise die Tests schneller. – evedovelli

0

Die oben genannten Antworten in einigen Fällen helfen kann, und die man eigentlich in einem meiner Situationen geholfen, aber bei Verwendung eines Carrierwave, die vorherige Lösung aus diese Frage hat diesmal nicht geklappt.

erste Ansatz:

Für das Hinzufügen von mir ein after :create löste das Problem für mich wie folgt aus:

after :create do |b| 
    b.update_column(:video_file, File.join(Rails.root, 'spec', 'fixtures', 'sample.mp4')) 
end 

Einstellung Inline-Videodatei wie video_file { File.new("#{Rails.root}/spec/fixtures/sample.mp4") } nicht funktioniert, und es wurde die Meldung von Fehlern.

Zweiter Ansatz:

eine Fabrik definieren wie folgt aus (personal_file auf Ihren Anlagenamen ändern):

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 

Und fügen Sie diese Zeilen an die config/environemnts/test.rb:

config.paperclip_defaults = { 
    url: "#{Rails.root}/spec/fixtures/:attachment/:filename", 
    use_timestamp: false 
} 
Verwandte Themen