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

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

Ответ 1

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

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

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

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

например:

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

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

например:

post :bookmark, :bulkfile => bulk_json

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

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

Ответ 2

Ответ Mori правильный, за исключением того, что в 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

Ответ 3

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

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

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

Ответ 4

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

Ответ 5

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

Ответ 6

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

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.

Он отлично работает.

Ура!

Ответ 7

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

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