【问题标题】:Rails Functional Test Case and Uploading Files to ActionDispatch::Http::UploadFileRails 功能测试用例和上传文件到 ActionDispatch::Http::UploadFile
【发布时间】:2011-05-29 12:51:36
【问题描述】:

我正在向远程存储文件的 Rails 应用程序添加测试。我正在使用默认的 Rails 功能测试。如何向它们添加文件上传?我有:

test "create valid person" do
  post(:create, :person => { :avatar => fixture_file_upload('avatar.jpeg') })
end

由于某种原因,这会上传 Tempfile 并导致 AWS/S3 gem 失败:

NoMethodError: undefined method `bytesize' for Tempfile

他们有什么方法可以让我使用ActionDispatch::Http::UploadedFile 进行测试,并且表现得更像使用网络浏览器进行测试时的表现吗? fixture_file_upload 是测试将文件上传到控制器的方法吗?如果是这样,为什么它不像浏览器那样工作?

请注意,我真的不想切换测试框架。谢谢!

【问题讨论】:

    标签: ruby-on-rails ruby gem functional-testing


    【解决方案1】:

    我使用 s3 gem 而不是 aws/s3 gem。造成这种情况的主要原因是不支持欧洲存储桶,而且 aws/s3 的开发似乎已停止。

    如果你想测试文件上传比使用fixtures_file_upload方法是正确的,它直接映射到Rack::Test::UploadedFile.new(你可以使用这个如果测试文件不在fixtures文件夹中)。

    但我也注意到 Rack::Test::Uploaded 文件对象的行为与 ActionDispatch::Http::UploadedFile 对象(即上传文件的类)并不完全相同。基本方法(original_filename、read、size、...)都可以工作,但在使用 file 方法时存在一些差异。所以限制你的控制器使用这些方法,一切都会好起来的。

    另一种可能的解决方案是创建一个 ActionDispatch::Http::Uploaded 文件对象并使用它:

    upload = ActionDispatch::Http::UploadedFile.new({
      :filename => 'avatar.jpeg',
      :type => 'image/jpeg',
      :tempfile => File.new("#{Rails.root}/test/fixtures/avatar.jpeg")
    })
    
    post :create, :person => { :avatar => upload }
    

    【讨论】:

    • 抱歉耽搁了,但这看起来很完美!非常感谢您的回答!
    • +1,使用 ActionDispatch::Http::UploadedFile 更安全,因为 Rack::Test::Uploaded API 与 Rails 不兼容。
    • 属性为content_type,但您需要将密钥 :type 传递给初始化程序。 (stackoverflow.com/questions/23899860/…)
    • upload 在参数中作为"#<ActionDispatch::Http::UploadedFile:0x007f9b6642a208>" 字符串
    • 我和@sohair有同样的问题。这个解决方案不起作用,文件只是以他提到的格式作为字符串到达​​控制器。
    【解决方案2】:

    我不熟悉 AWS/S3 gem,但您似乎没有正确使用 :avatar 参数。 bytesize 在 ruby​​1.9 中的 String 上定义。如果您在上传的文件上调用 read 并将其传递到 AWS/S3 会发生什么?

    【讨论】:

    • 我不认为这是问题所在。在浏览器中测试时,我的代码运行良好。我只需要添加对自动化测试的支持,并希望测试使用ActionDispatch::Http::UploadedFile(响应tempfile,允许访问磁盘上的文件)以便我可以集成。
    【解决方案3】:

    我建议使用模拟。 快速谷歌搜索显示:

    http://www.ibm.com/developerworks/web/library/wa-mockrails/index.html

    您应该能够创建一个对象来响应您想要的行为。主要用于单元测试环境,因此您可以单独测试您的东西,因为集成测试应该充分锻炼整个堆栈。但是,在这种情况下,我可以看到模拟 S3 服务会很有用,因为它需要花钱。

    【讨论】:

    • 感谢您的回复,但如果可能的话,我真的希望坚持使用简单的功能测试!我很乐意支付小额费用来测试 S3 服务(因为它是核心)。
    猜你喜欢
    • 1970-01-01
    • 2017-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-07
    • 1970-01-01
    相关资源
    最近更新 更多