Railsでファイルのアップロードをテストするにはどうすればよいですか?


101

JSONファイルを受け入れ、JSONファイルを処理してアプリケーションのユーザーメンテナンスを行うコントローラーがあります。ユーザーのテストではファイルのアップロードと処理が機能しますが、もちろん、テストでユーザーのメンテナンスをテストするプロセスを自動化したいと思います。機能テストフレームワークのコントローラーにファイルをアップロードするにはどうすればよいですか?

回答:


110

この質問を検索したところ、Stack Overflowでその回答は見つからなかった、またはその回答が見つからなかったが、他の場所で見つけたため、SOで利用できるようにしたい。

Railsフレームワークには関数fixture_file_uploadRails 2 Rails 3Rails 5)があり、指定されたファイルのフィクスチャディレクトリを検索し、機能テストでコントローラーのテストファイルとして使用できるようにします。それを使用するには:

1)アップロードするファイルをテスト用のフィクスチャ/ファイルサブディレクトリに配置します。

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ですか、それとも私だけですか?
アーネスト

@ChirantanはActionDispatch :: TestProcessに移動しました
ベンの作成者

これをFactoryGirlでどのように使用できますか?stackoverflow.com/questions/34677780/...
Richlewis

85

森の答えは正しいですが、Rails 3では「ActionController :: TestUploadedFile.new」の代わりに「Rack :: Test :: UploadedFile.new」を使用する必要があります。

作成されたファイルオブジェクトは、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が提供するActionController :: TestUploadedFileクラスを使用すると、次のように、コントローラ仕様のparamsハッシュでアップロードされたファイルを表すことができます。

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から非推奨となるようです。Rails 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.