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

J’ai un contrôleur qui est chargé d’accepter les fichiers JSON, puis de traiter les fichiers JSON pour effectuer une maintenance utilisateur pour notre application. En testant le téléchargement et le traitement du fichier, l’utilisateur souhaite bien sûr automatiser le processus de test de la maintenance de l’utilisateur lors de nos tests. Comment puis-je télécharger un fichier sur un contrôleur dans le cadre de test fonctionnel?

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

Le framework de rails a une fonction fixture_file_upload ( Rails 2 Rails 3 , Rails 5 ), qui recherchera le fichier spécifié dans votre répertoire de fixtures et le rendra disponible comme 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 tester.

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 atteindre l’action du contrôleur que vous souhaitez, en passant l’object renvoyé par fixture_file_upload comme paramètre du téléchargement.

par exemple:

post :bookmark, :bulkfile => bulk_json

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

Cela se déroulera dans le post-traitement simulé en utilisant une copie Tempfile du fichier dans votre répertoire des appareils, puis reviendra à votre test unitaire pour que vous puissiez commencer à examiner les résultats de l’article.

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’object fichier créé peut alors ê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 

Je pense qu’il est préférable d’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 le fichier temporaire).

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 paramètre hash 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 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 véritable modèle d’utilisateur.

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

Si vous utilisez des rails par défaut, testez-les avec Factory Girl. Bien au-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 fictive dans /test/images/100_100.jpg .

Cela fonctionne parfaitement.

À votre santé!

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 rendra la méthode fausse à la méthode ‘tempfile’, qui renverra le chemin vers le fichier chargé.