Bagaimana cara menguji unggahan file di rel?

102

Saya memiliki pengontrol yang bertanggung jawab untuk menerima file JSON dan kemudian memproses file JSON untuk melakukan pemeliharaan pengguna untuk aplikasi kami. Dalam pengujian pengguna, unggahan dan pemrosesan file berfungsi, tetapi tentu saja saya ingin mengotomatiskan proses pengujian pemeliharaan pengguna dalam pengujian kami. Bagaimana cara mengunggah file ke pengontrol dalam kerangka pengujian fungsional?

satwa
sumber

Jawaban:

110

Mencari pertanyaan ini dan tidak dapat menemukannya, atau jawabannya di Stack Overflow, tetapi menemukannya di tempat lain, jadi saya meminta untuk membuatnya tersedia di SO.

Kerangka kerja rel memiliki fungsi fixture_file_upload( Rails 2 Rails 3 , Rails 5 ), yang akan mencari direktori perlengkapan Anda untuk file yang ditentukan dan akan membuatnya tersedia sebagai file uji untuk pengontrol dalam pengujian fungsional. Untuk menggunakannya:

1) Letakkan file Anda untuk diunggah dalam pengujian di subdirektori perlengkapan / file Anda untuk pengujian.

2) Dalam pengujian unit Anda, Anda bisa mendapatkan file pengujian dengan memanggil fixture_file_upload ('path', 'mime-type').

misalnya:

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

3) panggil metode posting untuk menekan aksi pengontrol yang Anda inginkan, meneruskan objek yang dikembalikan oleh fixture_file_upload sebagai parameter untuk unggahan.

misalnya:

post :bookmark, :bulkfile => bulk_json

Atau di Rails 5: post :bookmark, params: {bulkfile: bulk_json}

Ini akan dijalankan melalui proses posting yang disimulasikan menggunakan salinan Tempfile dari file di direktori perlengkapan Anda dan kemudian kembali ke pengujian unit Anda sehingga Anda dapat mulai memeriksa hasil posting.

satwa
sumber
2
Ini tidak bekerja pada rail 3. Tampaknya file action_controller / test_process tidak tersedia di activesupport 3. Saya telah membuka pertanyaan baru untuk hal yang sama di sini - stackoverflow.com/questions/3966263/…
Chirantan
Tautan di jawaban Anda adalah 404, atau hanya untuk saya?
Ernest
@Chirantan itu dipindahkan ke ActionDispatch :: TestProcess
ben penulis
bagaimana ini bisa digunakan dengan FactoryGirl? stackoverflow.com/questions/34677780/…
Richlewis
85

Jawaban Mori benar, kecuali di Rails 3 dan bukan "ActionController :: TestUploadedFile.new" Anda harus menggunakan "Rack :: Test :: UploadedFile.new".

Objek file yang dibuat kemudian dapat digunakan sebagai nilai parameter dalam pengujian Rspec atau 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
Victor Grey
sumber
Metode ini adalah alternatif yang bagus saat perlengkapan Anda tidak berada di / test / fixture. Misalnya, jika Anda membuat beberapa file secara dinamis untuk pengujian, file tersebut mungkin ada di folder / tmp.
Olivier Amblet
25

Saya pikir lebih baik menggunakan ActionDispatch :: Http :: UploadedFile baru dengan cara ini:

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

Dengan cara ini Anda dapat menggunakan metode yang sama dengan yang Anda gunakan dalam validasi Anda (seperti misalnya tempfile).

David Morales
sumber
8

Dari The Rspec Book, B13.0:

Rails 'menyediakan kelas ActionController :: TestUploadedFile yang dapat digunakan untuk merepresentasikan file yang diunggah dalam hash params dari spesifikasi pengontrol, seperti ini:

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

Spesifikasi ini mengharuskan Anda memiliki gambar test_avatar.png di direktori spec / fixture. Ini akan mengambil file itu, mengunggahnya ke pengontrol, dan pengontrol akan membuat dan menyimpan model Pengguna yang sebenarnya.

Mori
sumber
2
Saya mendapatkan kesalahan "konstan ActionController :: TestUploadedFile" yang tidak diinisialisasi ketika saya menjalankan tes dengan kode ini. Ada hal lain yang saya perlukan dalam file?
Vini.g.fer
1
Tampaknya sudah ditinggalkan sejak Rails 2.3. Untuk Rails 3.0 dan seterusnya, inilah cara Anda melakukannya menggunakan perlengkapan
Sebastialonso
4

Anda ingin menggunakan fixture_file_upload . Anda akan meletakkan file tes Anda di subdirektori dari direktori perlengkapan dan kemudian meneruskan di jalur ke fixture_file_upload. Berikut adalah contoh kode , menggunakan upload file fixture

Rob Di Marco
sumber
1

Jika Anda menggunakan uji rel default dengan gadis pabrik. Baik di bawah kode.

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

Catatan: Anda harus menyimpan gambar tiruan /test/images/100_100.jpg .

Ini bekerja dengan sempurna.

Bersulang!

Manish Shrivastava
sumber
0

jika Anda mendapatkan file di pengontrol Anda dengan yang berikut ini

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

kemudian coba yang berikut ini dalam spesifikasi Anda:

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

Ini akan membuat metode palsu menjadi metode 'tempfile', yang akan mengembalikan jalur ke file yang dimuat.

Esenbek Kydyr uulu
sumber