2009-07-24 10 views
91

Ho un controller che è responsabile dell'accettazione dei file JSON e quindi dell'elaborazione dei file JSON per eseguire la manutenzione dell'utente per la nostra applicazione. Nel test degli utenti il ​​caricamento e l'elaborazione dei file funzionano, ma ovviamente vorrei automatizzare il processo di testare la manutenzione degli utenti nei nostri test. Come posso caricare un file su un controller nel framework dei test funzionali?Come si verifica un caricamento di file in rotaie?

risposta

99

Ha cercato questa domanda e non è riuscita a trovarla o la sua risposta su Stack Overflow, ma l'ho trovata altrove, quindi sto chiedendo di renderla disponibile su SO.

Il quadro rotaie ha una funzione fixture_file_upload (Rails 2Rails 3, Rails 5), che esegue una ricerca nella directory di apparecchi per il file specificato e lo renderà disponibile come file di test per il controller di test funzionali. Per utilizzarlo:

1) Inserire il file da caricare nel test nella sottodirectory fixtures/files per il test.

2) Nel test dell'unità è possibile ottenere il file di test chiamando fixture_file_upload ("percorso", "tipo mime").

es .:

bulk_json = fixture_file_upload('files/bulk_bookmark.json','application/json')

3) chiama il metodo post per colpire l'azione di controllo che si desidera, passando l'oggetto restituito dal fixture_file_upload come parametro per il caricamento.

esempio:

post :bookmark, :bulkfile => bulk_json

O in Rails 5: post :bookmark, params: {bulkfile: bulk_json}

Questo verrà eseguito attraverso il processo di post simulato utilizzando una copia File Temporanei del file nella directory di infissi e poi tornare alla vostra unità prova in modo da poter iniziare a esaminare i risultati del post.

+2

Questo non funziona sui binari 3. Il file action_controller/test_process non è disponibile nel supporto 3 attivo a quanto pare. Ho aperto una nuova domanda per lo stesso qui: http://stackoverflow.com/questions/3966263/attachment-fu-testing-in-rails-3 – Chirantan

+0

Il link nella tua risposta è 404 o è solo per me? – Ernest

+0

Complimenti e grazie mille! –

4

Si desidera utilizzare fixtures_file_upload. Metterai il tuo file di test in una sottodirectory della directory fixtures e poi passerai nel percorso a fixtures_file_upload. Ecco un example of code, utilizzando caricare file fixture

9

Dal Rspec Libro, B13.0:

Rails' fornisce un'ActionController :: TestUploadedFile classe che può essere usato per rappresentare un file caricato nella hash params di un Controller spec, in questo modo:

describe UsersController, "POST create" do 
    after do 
    # if files are stored on the file system 
    # be sure to clean them up 
    end 

    it "should be able to upload a user's avatar image" do 
    image = fixture_path + "/test_avatar.png" 
    file = ActionController::TestUploadedFile.new image, "image/png" 
    post :create, :user => { :avatar => file } 
    User.last.avatar.original_filename.should == "test_avatar.png" 
    end 
end 

questa specifica richiederebbe che si dispone di un'immagine test_avatar.png nella directory spec/fixtures. Dovrebbe prendere quel file, caricarlo sul controller, e il controller creerebbe e salverà un modello utente reale.

+1

Viene visualizzato un errore "costante non inizializzato ActionController :: TestUploadedFile" quando eseguo un test con questo codice. Qualcos'altro che avrei bisogno di richiedere nel file? –

+0

Sembra essere deprecato già da Rails 2.3. Per Rails 3.0 in poi, [ecco come lo si fa] (http://apidock.com/rails/ActionDispatch/TestProcess/fixture_file_upload) utilizzando i dispositivi – Sebastialonso

0

se hai trovato il file nel controller con il seguente

json_file = params[:json_file] 
FileUtils.mv(json_file.tempfile, File.expand_path('.')+'/tmp/newfile.json') 

quindi provare il seguente nelle vostre specifiche:

json_file = mock('JsonFile') 
json_file.should_receive(:tempfile).and_return("files/bulk_bookmark.json") 
post 'import', :json_file => json_file 
response.should be_success 

questo renderà il metodo falso per il metodo 'tempfile', che restituirà il percorso del file caricato.

76

La risposta di Mori è corretta, tranne che in Rails 3 invece di "ActionController :: TestUploadedFile.new" devi utilizzare "Rack :: Test :: UploadedFile.new".

L'oggetto file creato può quindi essere utilizzato come valore di parametro nei test Rspec o TestUnit.

test "image upload" do 
    test_image = path-to-fixtures-image + "/Test.jpg" 
    file = Rack::Test::UploadedFile.new(test_image, "image/jpeg") 
    post "/create", :user => { :avatar => file } 
    # assert desired results 
    post "/create", :user => { :avatar => file }  

    assert_response 201 
    assert_response :success 
end 
+0

Questo metodo è una buona alternativa quando i dispositivi non si trovano in/test/fixtures. Se si generano dinamicamente alcuni file per i test, ad esempio, potrebbero essere in una cartella/tmp. –

+2

Funziona perfettamente anche con Rails 4. Grazie! – Waseem

22

penso che sia meglio utilizzare la nuova ActionDispatch :: HTTP :: UploadedFile questo modo:

uploaded_file = ActionDispatch::Http::UploadedFile.new({ 
    :tempfile => File.new(Rails.root.join("test/fixtures/files/test.jpg")) 
}) 
assert model.valid? 

In questo modo è possibile utilizzare gli stessi metodi in uso nelle vostre convalide (come ad esempio tempfile).

1

Se si utilizza il test delle guide predefinite con factory girl. Bene sotto il codice.

factory :image_100_100 do 
    image File.new(File.join(::Rails.root.to_s, "/test/images", "100_100.jpg")) 
end 

Nota: si dovrà tenere d'immagine fittizia in /test/images/100_100.jpg.

Funziona perfettamente.

Cheers!

Problemi correlati