web-dev-qa-db-fra.com

Comment tester un téléchargement de fichier dans des rails?

J'ai un contrôleur qui est responsable d'accepter les fichiers JSON puis de traiter les fichiers JSON pour effectuer une maintenance utilisateur pour notre application. Lors des tests utilisateur, le téléchargement et le traitement des fichiers fonctionnent, mais bien sûr, j'aimerais automatiser le processus de test de la maintenance utilisateur dans nos tests. Comment puis-je télécharger un fichier sur un contrôleur dans le cadre de test fonctionnel?

98
animal

J'ai recherché cette question et je n'ai pas pu la trouver, ni sa réponse sur Stack Overflow, mais je l'ai trouvée ailleurs, donc je demande de la rendre disponible sur SO.

Le cadre Rails a une fonction fixture_file_upload ( Rails 2Rails , Rails 5 ), qui recherchera dans votre répertoire des appareils le fichier spécifié et le rendra disponible en tant que fichier de test pour le contrôleur lors des tests fonctionnels. Pour l'utiliser:

1) Mettez votre fichier à télécharger dans le test dans votre sous-répertoire fixtures/files pour le test.

2) Dans votre test unitaire, vous pouvez obtenir votre fichier de test en appelant fixture_file_upload ('path', 'mime-type').

par exemple.:

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

3) appelez la méthode post pour frapper l'action de contrôleur que vous voulez, en passant l'objet renvoyé par fixture_file_upload comme paramètre pour le téléchargement.

par exemple.:

post :bookmark, :bulkfile => bulk_json

Ou en Rails 5: post :bookmark, params: {bulkfile: bulk_json}

Cela se déroulera à travers le processus de publication simulé en utilisant une copie Tempfile du fichier dans votre répertoire d'appareils, puis reviendra à votre test unitaire afin que vous puissiez commencer à examiner les résultats de la publication.

109
animal

La réponse de Mori est correcte, sauf que dans Rails 3 au lieu de "ActionController :: TestUploadedFile.new", vous devez utiliser "Rack :: Test :: UploadedFile.new".

L'objet fichier créé peut ensuite être utilisé comme valeur de paramètre dans les tests Rspec ou 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
83
Victor Grey

Je pense qu'il vaut mieux utiliser le nouveau ActionDispatch :: Http :: UploadedFile de cette façon:

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

De cette façon, vous pouvez utiliser les mêmes méthodes que vous utilisez dans vos validations (comme par exemple tempfile).

23
David Morales

Extrait du livre Rspec, B13.0:

Rails ’fournit une classe ActionController :: TestUploadedFile qui peut être utilisée pour représenter un fichier téléchargé dans le hachage de paramètres d'une spécification de contrôleur, comme ceci:

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

Cette spécification nécessiterait que vous ayez une image test_avatar.png dans le répertoire spec/fixtures. Il prendrait ce fichier, le téléchargerait sur le contrôleur, et le contrôleur créerait et enregistrerait un vrai modèle utilisateur.

8
Mori

Vous souhaitez utiliser fixtures_file_upload . Vous placerez votre fichier de test dans un sous-répertoire du répertoire fixtures puis passerez le chemin vers fixtures_file_upload. Voici un exemple de code , utilisant le téléchargement de fichiers de fixture

4
Rob Di Marco

Si vous utilisez par défaut Rails test avec une fille d'usine. Bien en dessous du code.

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

Remarque: vous devrez conserver une image factice dans /test/images/100_100.jpg.

Cela fonctionne parfaitement.

À votre santé!

1

si vous obtenez le fichier dans votre contrôleur avec les éléments suivants

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

puis essayez ce qui suit dans vos spécifications:

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

Cela transformera la fausse méthode en méthode 'tempfile', qui renverra le chemin vers le fichier chargé.

0
Esenbek Kydyr uulu