You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

升级Rails与Ruby后使用Rack::Test::UploadedFile报错:无法将Hash转为String

问题分析与解决

这个错误完全和测试随机执行无关,问题出在你对Rack::Test::UploadedFile的初始化参数使用错误上。

错误原因

Rack::Test::UploadedFile的构造函数第一个参数要求是文件路径的字符串,而你传入了一个Hash对象,这就触发了no implicit conversion of Hash into String的类型错误——Ruby没办法把Hash自动转成构造函数需要的字符串路径。

之前的ActionDispatch::Http::UploadedFile可能支持Hash形式的参数,但Rack::Test::UploadedFile的API设计不同,升级后要注意这个差异。

正确写法

你有两种简洁的正确写法可选:

  1. 基础写法(直接指定文件路径和MIME类型):
it "should create candidate" do
  file_path = "#{Rails.root}/spec/files/example.csv"
  file = Rack::Test::UploadedFile.new(file_path, 'text/csv')
  Candidate.import_csv(file)
  expect(Candidate.find_by(name: "Stack Overflow").email).to eq "test@stackoverflow.com"
end
  1. 显式指定文件名(如果需要自定义和实际文件不同的文件名时):
it "should create candidate" do
  file_path = "#{Rails.root}/spec/files/example.csv"
  file = Rack::Test::UploadedFile.new(
    file_path,
    'text/csv',
    filename: 'example.csv' # 这里可以自定义文件名
  )
  Candidate.import_csv(file)
  expect(Candidate.find_by(name: "Stack Overflow").email).to eq "test@stackoverflow.com"
end

额外说明

一般情况下不需要手动传入tempfile参数,Rack::Test::UploadedFile会自动根据你提供的文件路径创建对应的临时文件对象,只有在特殊场景下(比如手动构造内存中的临时文件)才需要手动指定tempfile。

内容的提问来源于stack exchange,提问作者rails_newbie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:30:09