2009-07-24 24 views
91

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?¿Cómo pruebo la carga de un archivo en los rieles?

Respuesta

99

Ha buscado esta pregunta y no pudo encontrarla, o su respuesta en Stack Overflow, pero lo encontré en otro lado, por lo que le pido que esté disponible en SO.

El marco carriles tiene una función fixture_file_upload (Rails 2Rails 3, Rails 5), que buscará en su directorio de accesorios para el archivo especificado y lo hará disponible como un archivo de prueba de la controladora 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 ('ruta', 'mime-type').

ej .:

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

3) llamar al método post para golpear la acción del controlador que desee, pasando el objeto devuelto por fixture_file_upload como parámetro para la carga.

por ejemplo:

post :bookmark, :bulkfile => bulk_json

O en los carriles 5: post :bookmark, params: {bulkfile: bulk_json}

Esto ejecutará a través del proceso de post simulada utilizando una copia de archivo temporal del archivo en el directorio de accesorios y luego regresar a su unidad prueba para que pueda comenzar a examinar los resultados de la publicación.

+2

Esto no funciona en los rieles 3. Parece que el archivo action_controller/test_process no está disponible en activesupport 3. He abierto una nueva pregunta para el mismo aquí - http://stackoverflow.com/questions/3966263/attachment-fu-testing-in-rails-3 – Chirantan

+0

El enlace en su respuesta es 404, ¿o es solo para mí? – Ernest

+0

¡Me gusta y muchas gracias! –

4

Quiere 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. He aquí un example of code, utilizando archivo de datos subir

9

De La Rspec libro, B13.0:

rieles proporciona una ActionController :: TestUploadedFile clase que puede ser usado para representar un archivo cargado en el hash params de un especificación de controlador, como esto:

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 tiene una imagen test_avatar.png en el directorio spec/accesorios. Tomaría ese archivo, lo cargaría al controlador, y el controlador crearía y guardaría un modelo de Usuario real.

+1

Aparece un error de "constante no inicializada ActionController :: TestUploadedFile" cuando ejecuto una prueba con este código. ¿Algo más que necesite solicitar en el archivo? –

+0

Parece estar obsoleto tan pronto como Rails 2.3. Para Rails 3.0 en adelante, [así es como lo hace] (http://apidock.com/rails/ActionDispatch/TestProcess/fixture_file_upload) usando los accesorios – Sebastialonso

0

si usted está recibiendo el archivo en su controlador con la siguiente

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

continuación, 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 hará que el método falsa al método 'tempfile', que devolverá la ruta al archivo cargado.

76

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 
+0

Este método es una buena alternativa cuando sus dispositivos no se encuentran en/test/fixtures. Si genera dinámicamente algunos archivos para las pruebas, por ejemplo, es posible que estén en una carpeta/tmp. –

+2

Esto funciona sin problemas con Rails 4 también. ¡Gracias! – Waseem

22

creo que es mejor utilizar el nuevo ActionDispatch :: http :: UploadedFile esta manera:

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

De esta manera se pueden utilizar los mismos métodos que está utilizando en sus validaciones (como, por ejemplo, archivo temporal).

1

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: tendrá que mantener una imagen ficticia en /test/images/100_100.jpg.

Funciona perfectamente.

¡Salud!

Cuestiones relacionadas