我有这样的控制器方法:
# POST /v1/scans
def create
p params
uploaded_file = params["pm_file"]
filename = uploaded_file.original_filename
content = uploaded_file.read
parser = ParserStrategy.parser_for filename
file_scan = parser.parse_content content, filename, @api_token.organisation
data = {'scan.id': file_scan.id.to_s}
render json: data, status: :created
rescue => e
Rails.logger.error e.message
Rails.logger.error e.backtrace.join("\n")
end
文件上传正常。如果我用CURL像这样测试它:
curl -H "Authorization: Bearer QGoEUTK5htI6IT1zyLgKWPqBxv1EXrf7ApSFuuSi" -X POST http://localhost:3000/v1/scans -F [email protected]
我得到了预期的结果,参数输出看起来像这样:
Parameters: {"pm_file"=>#<ActionDispatch::Http::UploadedFile:0x00007f914bae9708 @tempfile=#<Tempfile:/var/folders/ng/h_lxfcf13m71_kgr70_f79hr0000gn/T/RackMultipart20200521-75565-r5a4k1.json>, @original_filename="composer.json", @content_type="application/octet-stream", @headers="Content-Disposition: form-data; name=\"pm_file\"; filename=\"composer.json\"\r\nContent-Type: application/octet-stream\r\n">} <ActionController::Parameters {"pm_file"=>#<ActionDispatch::Http::UploadedFile:0x00007f914bae9708 @tempfile=#<Tempfile:/var/folders/ng/h_lxfcf13m71_kgr70_f79hr0000gn/T/RackMultipart20200521-75565-r5a4k1.json>, @original_filename="composer.json", @content_type="application/octet-stream", @headers="Content-Disposition: form-data; name=\"pm_file\"; filename=\"composer.json\"\r\nContent-Type: application/octet-stream\r\n">, "controller"=>"v1/scans", "action"=>"create"} permitted: false>
我可以清楚地看到
pm_file
是UploadedFile类型的对象。现在,我想为此编写一个自动化测试。用minitest做到了:
test "should return 201 because valid request" do file_path = "#{Rails.root}/test/fixtures/files/composer/composer.json" composer_file = Rack::Test::UploadedFile.new(file_path, 'application/json', false) post v1_scans_url, params: { pm_file: composer_file }, headers: { "Authorization" => "Bearer #{@token}" }, as: :json assert_response 201 end
不幸的是,这不起作用。然后我触发测试,参数输出看起来像这样:
Parameters: {"pm_file"=>{"original_filename"=>"composer.json", "tempfile"=>"#<File:0x00007fd2a11dff30>", "content_type"=>"application/json"}, "scan"=>{"pm_file"=>{"original_filename"=>"composer.json", "tempfile"=>"#<File:0x00007fd2a11dff30>", "content_type"=>"application/json"}}}
现在
pm_file
不再是UploadedFile类型的Object,它是一个哈希。代码失败并显示:
undefined method `original_filename' for #<ActionController::Parameters:0x00007fd2859c2278>
fixture_file_upload
同样。该测试带来完全相同的结果:
test "should return 201 because valid request" do file_path = "#{Rails.root}/test/fixtures/files/composer/composer.json" composer_file = fixture_file_upload("#{Rails.root}/test/fixtures/files/composer/composer.json",'application/json') post v1_scans_url, params: { pm_file: composer_file }, headers: { "Authorization" => "Bearer #{@token}" }, as: :json assert_response 201 end
我做错了什么?如何在Rails 6中正确测试文件上传?
我有这样的控制器方法:#POST / v1 / scans def create p params upload_file = params [“ pm_file”]文件名= upload_file.original_filename内容= ...