Rails에서 파일 업로드를 어떻게 테스트합니까?


101

JSON 파일을 수락 한 다음 JSON 파일을 처리하여 애플리케이션에 대한 사용자 유지 관리를 수행하는 컨트롤러가 있습니다. 사용자 테스트에서 파일 업로드 및 처리가 작동하지만 물론 테스트에서 사용자 유지 관리 테스트 프로세스를 자동화하고 싶습니다. 기능 테스트 프레임 워크에서 컨트롤러에 파일을 업로드하려면 어떻게해야합니까?

답변:


110

이 질문을 검색했지만 Stack Overflow에서 또는 그 답변을 찾을 수 없었지만 다른 곳에서 찾았으므로 SO에서 사용할 수 있도록 요청하고 있습니다.

Rails 프레임 워크에는 지정된 파일에 대한 조명기 디렉토리를 검색하고 기능 테스트에서 컨트롤러의 테스트 파일로 사용할 수 있도록 하는 기능 fixture_file_upload( Rails 2 Rails 3 , Rails 5 )이 있습니다. 그것을 사용하려면 :

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
이것은 rails 3에서 작동하지 않습니다. action_controller / test_process 파일은 activesupport 3에서 사용할 수 없습니다. - 나는 여기에 동일한에 대한 새로운 질문을 열었습니다 stackoverflow.com/questions/3966263/...
Chirantan

대답의 링크는 404입니까, 아니면 나만을위한 것입니까?
Ernest

@Chirantan 그것은 ActionDispatch :: TestProcess로 이동되었습니다
ben author

FactoryGirl에서 어떻게 사용할 수 있습니까? stackoverflow.com/questions/34677780/…
Richlewis

85

"ActionController :: TestUploadedFile.new"대신 Rails 3에서 "Rack :: Test :: UploadedFile.new"를 사용해야한다는 점을 제외하면 Mori의 대답은 정확합니다.

생성 된 파일 개체는 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

이 방법은 조명기가 / test / fixtures에 없을 때 좋은 대안입니다. 예를 들어 테스트를 위해 일부 파일을 동적으로 생성하면 대신 / tmp 폴더에있을 수 있습니다.
Olivier Amblet 2012 년

25

새로운 ActionDispatch :: Http :: UploadedFile을 다음과 같이 사용하는 것이 더 낫다고 생각합니다.

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

이렇게하면 유효성 검사에 사용하는 것과 동일한 방법을 사용할 수 있습니다 (예 : tempfile).


8

Rspec Book, B13.0에서 :

Rails는 다음과 같이 컨트롤러 사양의 params 해시에서 업로드 된 파일을 나타내는 데 사용할 수있는 ActionController :: TestUploadedFile 클래스를 제공합니다.

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

이 스펙을 사용하려면 spec / fixtures 디렉토리에 test_avatar.png 이미지가 있어야합니다. 해당 파일을 가져와 컨트롤러에 업로드하면 컨트롤러가 실제 사용자 모델을 만들고 저장합니다.


2
이 코드로 테스트를 실행하면 "초기화되지 않은 상수 ActionController :: TestUploadedFile"오류가 발생합니다. 파일에 필요한 다른 것이 있습니까?
Vini.g.fer

1
Rails 2.3부터는 더 이상 사용되지 않는 것 같습니다. 이후 레일 3.0, 여기 당신이 그것을 할 방법은 기구 사용
Sebastialonso


1

공장 소녀와 함께 기본 레일 테스트를 사용하는 경우. 코드 아래 괜찮습니다.

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.

완벽하게 작동합니다.

건배!


0

다음과 같이 컨트롤러에서 파일을 얻는 경우

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'메서드에 가짜 메서드가 생성됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.