ruby on rails - test - ¿Cómo pruebo la carga de un archivo en los rieles?
rails active storage tutorial (7)
Tengo un controlador que es responsable de aceptar los archivos JSON y luego procesar los archivos JSON para hacer un poco de mantenimiento del usuario para nuestra aplicación. Al probar el usuario, la carga de archivos y el procesamiento funcionan, pero por supuesto me gustaría automatizar el proceso de prueba del mantenimiento del usuario en nuestras pruebas. ¿Cómo puedo cargar un archivo a un controlador en el marco de prueba funcional?
Busqué esta pregunta y no pude encontrarla, o su respuesta en , pero la encontré en otro lado, así que le pido que esté disponible en SO.
The Rails Framework tiene una función fixture_file_upload ( Rails 2 Rails 3 , Rails 5 ), que buscará en el directorio de dispositivos el archivo especificado y lo pondrá a disposición como un archivo de prueba para el controlador en las pruebas funcionales. Para usarlo:
1) Coloque su archivo para ser cargado en la prueba en su subdirectorio de accesorios / archivos para la prueba.
2) En su prueba de unidad, puede obtener su archivo de prueba llamando a fixture_file_upload (''path'', ''mime-type'').
p.ej:
bulk_json = fixture_file_upload(''files/bulk_bookmark.json'',''application/json'')
3) llame al método de publicación para presionar la acción del controlador que desee, pasando el objeto devuelto por fixture_file_upload como el parámetro para la carga.
p.ej:
post :bookmark, :bulkfile => bulk_json
O en Rails 5: post :bookmark, params: {bulkfile: bulk_json}
Esto se ejecutará a través del proceso post simulado utilizando una copia Tempfile del archivo en el directorio de sus accesorios y luego volverá a su prueba unitaria para que pueda comenzar a examinar los resultados de la publicación.
Creo que es mejor usar el nuevo ActionDispatch :: Http :: UploadedFile de esta manera:
uploaded_file = ActionDispatch::Http::UploadedFile.new({
:tempfile => File.new(Rails.root.join("test/fixtures/files/test.jpg"))
})
assert model.valid?
De esta forma, puede usar los mismos métodos que está utilizando en sus validaciones (como por ejemplo, archivo de temp).
De The Rspec Book, B13.0:
Rails ''proporciona una clase ActionController :: TestUploadedFile que se puede usar para representar un archivo cargado en el hash de parámetros de una especificación de controlador, como este:
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
Esta especificación requeriría que tenga una imagen test_avatar.png en el directorio spec / fixtures. Tomaría ese archivo, lo cargaría al controlador, y el controlador crearía y guardaría un modelo de Usuario real.
Desea usar fixtures_file_upload . Pondrá su archivo de prueba en un subdirectorio del directorio de accesorios y luego pasará en la ruta a fixtures_file_upload. Aquí hay un ejemplo de código , usando la carga del archivo de dispositivo
La respuesta de Mori es correcta, excepto que en Rails 3 en lugar de "ActionController :: TestUploadedFile.new" debe usar "Rack :: Test :: UploadedFile.new".
El objeto de archivo que se crea se puede usar como un valor de parámetro en las pruebas Rspec o 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
Si usa la prueba de rieles predeterminada con factory girl. Fino debajo del código.
factory :image_100_100 do
image File.new(File.join(::Rails.root.to_s, "/test/images", "100_100.jpg"))
end
Nota: deberá mantener una imagen ficticia en /test/images/100_100.jpg
.
Funciona perfectamente
¡Aclamaciones!
si obtiene el archivo en su controlador con la siguiente
json_file = params[:json_file]
FileUtils.mv(json_file.tempfile, File.expand_path(''.'')+''/tmp/newfile.json'')
entonces intente lo siguiente en sus especificaciones:
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
Esto convertirá el método falso en el método ''tempfile'', que devolverá la ruta al archivo cargado.