Как проверить загрузку файла в рельсах?

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


person animal    schedule 24.07.2009    source источник


Ответы (7)


Искал этот вопрос и не смог найти его или ответа на него в Stack Overflow, но нашел его в другом месте, поэтому я прошу сделать его доступным на SO.

Фреймворк rails имеет функцию fixture_file_upload (Rails 2 Rails 3, Rails 5), который выполнит поиск указанного файла в каталоге фикстур и сделает его доступен как тестовый файл для контроллера при функциональном тестировании. Чтобы использовать это:

1) Поместите файл, который будет загружен в тест, в подкаталог fixtures / files для тестирования.

2) В модульном тесте вы можете получить файл тестирования, вызвав fixture_file_upload ('path', 'mime-type').

e.g.:

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

3) вызовите метод post, чтобы выполнить нужное действие контроллера, передав объект, возвращаемый fixture_file_upload, в качестве параметра для загрузки.

e.g.:

post :bookmark, :bulkfile => bulk_json

Или в Rails 5: post :bookmark, params: {bulkfile: bulk_json}

Это будет проходить через смоделированный пост-процесс с использованием копии файла Tempfile в вашем каталоге фикстур, а затем вернется к вашему модульному тесту, чтобы вы могли начать изучать результаты публикации.

person animal    schedule 24.07.2009
comment
Это не работает на рельсах 3. Кажется, файл action_controller / test_process недоступен в activesupport 3. Я открыл новый вопрос для этого же здесь - stackoverflow.com/questions/3966263/ - person Chirantan; 19.10.2010
comment
Ссылка в вашем ответе 404, или это только у меня? - person Ernest; 14.12.2010
comment
@Chirantan перемещен в ActionDispatch :: TestProcess - person ben author; 16.11.2011
comment
как это можно использовать с FactoryGirl? stackoverflow.com/ questions / 34677780 / - person Richlewis; 08.01.2016

Ответ Мори правильный, за исключением того, что в 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
person Victor Grey    schedule 09.01.2011
comment
Этот метод является хорошей альтернативой, когда ваши фикстуры не находятся в / test / fixtures. Если вы, например, динамически генерируете некоторые файлы для тестов, они могут находиться в папке / tmp. - person Olivier Amblet; 11.09.2012

Я думаю, что лучше использовать новый ActionDispatch :: Http :: UploadedFile следующим образом:

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

Таким образом, вы можете использовать те же методы, что и при валидации (например, tempfile).

person David Morales    schedule 14.03.2012

Из книги Rspec, B13.0:

Rails 'предоставляет класс ActionController :: TestUploadedFile, который можно использовать для представления загруженного файла в хэше params спецификации контроллера, например:

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 в каталоге spec / fixtures. Он возьмет этот файл, загрузит его в контроллер, и контроллер создаст и сохранит реальную модель пользователя.

person Mori    schedule 05.11.2010
comment
Когда я запускаю тест с этим кодом, я получаю сообщение об ошибке неинициализированной константы ActionController :: TestUploadedFile. Что еще мне может понадобиться в файле? - person Vini.g.fer; 21.05.2015
comment
Кажется, он устарел еще в Rails 2.3. Для Rails 3.0 и более поздних версий вот как это сделать с помощью фикстур. - person Sebastialonso; 09.07.2016

Вы хотите использовать fixtures_file_upload. Вы поместите свой тестовый файл в подкаталог каталога fixtures, а затем передадите путь к fixtures_file_upload. Вот пример кода с использованием загрузки файла фикстуры

person Rob Di Marco    schedule 24.07.2009

Если вы используете тест рельсов по умолчанию с заводской девушкой. Штраф под кодом.

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.

Работает отлично.

Ваше здоровье!

person Manish Shrivastava    schedule 05.06.2014

если вы получаете файл в свой контроллер со следующими

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, который вернет путь к загруженному файлу.

person Esenbek Kydyr uulu    schedule 14.12.2010