🍎

RailsのAPIで画像をアップロードする時のテストの書き方

2023/03/01に公開

詰まったところ

https://swagger.io/docs/specification/describing-request-body/file-upload/
↑の公式情報をもとにswagger.yamlを下のように修正したい

requestBody:
  content:
    multipart/form-data: # ここのメディアタイプを変えるのが大事なのか。ふむふむ
      schema:
        type: object
        properties:
          file:
            type: string
            format: binary

テストをこんな感じで書いて実行してみたが。。。

post('upload') do
  consumes 'multipart/form-data' # この記述でrswagがmultipart/form-dataにしてくれる
  parameter name: file, in: :body, schema: ...省略
  response(204, 'successful') do
    let(:file) { fixture_file_upload(Rails.root.join('spec/fixtures/test.png'), 'image/png') }
    run_test! do
      ...省略
    end
  end
end

パラメーターにファイルが渡されてないぞ???🤔

[1] pry(#<UploadsController>)> params
=> <ActionController::Parameters {"format"=>:json, "controller"=>"uploads", "action"=>"create"} permitted: false>

解決策

parameterの部分をin: :bodyではなくin: :formDataにすることで解決

post('upload') do
  consumes 'multipart/form-data'
  parameter name: file, in: :formData # ここをformDataにする
  response(204, 'successful') do
    let(:file) { fixture_file_upload(Rails.root.join('spec/fixtures/test.png'), 'image/png') }
    run_test! do
      ...省略
    end
  end
end

パラメーター

[1] pry(#<UploadsController>)> params
# ちゃんとActionDispatchが渡ってきた!!
=> <ActionController::Parameters {"file"=>#<ActionDispatch::Http::UploadedFile:0x00000001 ...省略>

関連する箇所のみを抜き出して記述しているので矛盾があったらすいません。
要するにconsumes 'multipart/form-data'in: :formDataを使うんだなということを理解していただければと。

APIがどうやって情報を受け渡ししているのか学ぶきっかけになりよかったです。

Discussion