【问题标题】:Mocking file uploads in Rails 3.1 controller tests在 Rails 3.1 控制器测试中模拟文件上传
【发布时间】:2011-10-17 12:08:40
【问题描述】:

我的控制器访问上传文件的tempfile 属性并将其传递给另一个模拟组件。我的测试代码有

  @file = mock(Object)
  @file.stub_chain(:tempfile, :path).and_return('thefile.zip')
  # ...
  post :create, :file => @file

控制器代码调用params[:file].tempfile.path

从 Rails 3.0 升级到 3.1 后,上述行开始失败,并显示

undefined method `tempfile' for "#[RSpec::Mocks::Mock:0x2b0d9a0 @name=Object]":String

也就是说,Rails 3.1 自动将params[:file] 转换为字符串。

通过浏览器手动测试时,代码可以正常工作。我尝试使用fixture_file_upload,参数变成了File 对象,但它没有tempfile 方法。

那么如何将任意模拟对象作为参数传递给 Rails 3.1 中的操作?

【问题讨论】:

    标签: file-upload mocking ruby-on-rails-3.1 rspec-rails


    【解决方案1】:

    终于找到this,说明fixture_file_upload返回的东西虽然有@tempfile成员,但缺少reader方法。解决如下

      FileUtils.touch('file.zip') # fixture_file_upload needs the file to exist
      @file = fixture_file_upload('file.zip')
      class << @file
        # The reader method is present in a real invocation,
        # but missing from the fixture object for some reason (Rails 3.1.1)
        attr_reader :tempfile
      end
    

    【讨论】:

      【解决方案2】:

      我是这样转的

      upload_file = fixture_file_upload('files/stats_upload.csv', 'text/csv')
      upload_file.stubs(:tempfile).returns(upload_file)
      

      【讨论】:

      • 为了使用它,您需要将gem 'mocha' 添加到您的Gemfile
      • NoMethodError: # 的未定义方法“存根”
      【解决方案3】:

      我提出了一个拉取请求来解决这个问题,如果你喜欢请+1:https://github.com/brynary/rack-test/pull/67

      【讨论】:

      • 您的 pull 似乎已被合并,但从 Rails 3.2.13rc2 开始,使用 rack-test 0.6.2,我仍然不得不使用上述 @mpartel 的解决方法
      • 是否有机会获得包含此修复的版本?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-03
      • 1970-01-01
      • 2012-08-20
      相关资源
      最近更新 更多