Як перевірити завантаження файлів у рейках?


102

У мене є контролер, який відповідає за прийняття файлів JSON, а потім обробку файлів JSON, щоб виконати деяке обслуговування користувачів нашої програми. Під час тестування користувачем працює завантаження та обробка файлів, але, звичайно, я хотів би автоматизувати процес тестування обслуговування користувачів у нашому тестуванні. Як я можу завантажити файл до контролера в рамках функціонального тестування?

Відповіді:


110

Шукав це питання і не зміг його знайти або відповісти на Stack Overflow, але знайшов його в іншому місці, тому я прошу зробити його доступним на SO.

Рамка рейки має функцію fixture_file_upload( Rails 2 Rails 3 , Rails 5 ), яка здійснюватиме пошук у вашому каталозі світильників за вказаним файлом та зробить його доступним як тестовий файл для контролера у функціональному тестуванні. Щоб використовувати його:

1) Помістіть свій файл для завантаження в тест у вашому пристосуванні / файлах, підкаталозі для тестування.

2) У вашому тестовому модулі ви можете отримати свій тестовий файл, зателефонувавши fixture_file_upload ('path', 'mime-type').

наприклад:

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

3) викликайте метод публікації, щоб потрапити на потрібну дію контролера, передаючи об'єкт, повернутий fixture_file_upload як параметр для завантаження.

наприклад:

post :bookmark, :bulkfile => bulk_json

Або в Rails 5: post :bookmark, params: {bulkfile: bulk_json}

Це відбудеться через модельований процес публікації, використовуючи копію файлу Tempfile у вашому каталозі світильників, а потім повернеться до тесту одиниці, щоб ви могли розпочати вивчення результатів публікації.


2
Це не працює на рейках 3. Файл action_controller / test_process недоступний у програмі activesupport 3, здається. Я відкрив нове питання для того ж тут - stackoverflow.com/questions/3966263 / ...
Chirantan

Посилання у вашій відповіді 404, чи це просто для мене?
Ернест

@Chirantan переміщено до ActionDispatch :: TestProcess
автор авторів

як це можна використовувати з FactoryGirl? stackoverflow.com/questions/34677780 / ...
Richlewis

86

Відповідь Морі правильна, за винятком того, що в Rails 3 замість "ActionController :: TestUploadedFile.new" ви повинні використовувати "Rack :: Test :: UploadedFile.new".

Потім створений об’єкт файлу може використовуватися як значення параметра в тестах Rspec або 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

Цей метод є чудовою альтернативою, коли ваші світильники розташовані не в / test / світильниках. Якщо, наприклад, ви генеруєте динамічно деякі файли для тестів, вони можуть бути замість папки / tmp.
Олів'є Амблет

25

Я думаю, що краще використовувати новий ActionDispatch :: Http :: UploadedFile таким чином:

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

Таким чином ви можете використовувати ті самі методи, які ви використовуєте під час перевірки (як, наприклад, tempfile).


8

З книги про Rspec, B13.0:

Rails 'забезпечує клас ActionController :: TestUploadedFile, який може бути використаний для представлення завантаженого файлу в хеш-парамах специфікації контролера, наприклад:

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

Для цієї специфікації потрібно мати тест test_avatar.png у каталозі специфікації / світильників. Цей файл знадобиться, завантажить його в контролер, і контролер створить і збереже реальну модель користувача.


2
Я отримую помилку "неініціалізованої постійної ActionController :: TestUploadedFile" під час запуску тесту з цим кодом. Що-небудь ще мені потрібно буде вимагати у файлі?
Vini.g.fer

1
Здається, це застаріло ще на рейках 2.3. Для Rails 3.0 далі, ось як це робити за допомогою світильників
Себастіалонсо

4

Ви хочете використовувати fixtures_file_upload . Ви помістите свій тестовий файл у підкаталог каталогу світильників, а потім перейдете до шляху до fixtures_file_upload. Ось приклад коду за допомогою завантаження файлів кріплення


1

Якщо ви використовуєте тест рейки за замовчуванням із заводською дівчиною Тонкий код нижче.

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

Примітка: вам потрібно буде зберегти фіктивне зображення /test/images/100_100.jpg.

Це прекрасно працює.

Ура!


0

якщо ви отримуєте файл у свій контролер із наступним

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

то спробуйте наступне у своїх специфікаціях:

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

Це зробить підроблений метод методом 'tempfile', який поверне шлях до завантаженого файлу.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.