Mocking file uploads in Rails 3.1 controller tests

爷,独闯天下 提交于 2019-12-21 04:12:32

问题


My controller accesses the tempfile attribute of an uploaded file and passes it to another mocked component. My test code has

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

and the controller code calls params[:file].tempfile.path.

After upgrading from Rails 3.0 to 3.1, the above line started failing with

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

That is, Rails 3.1 converted params[:file] to a string automatically.

The code works properly when tested manually through a browser. I tried to use fixture_file_upload and the parameter became a File object but it had no tempfile method.

So how do I pass an arbitrary mock object as a parameter to an action in Rails 3.1?


回答1:


Finally found this, which tells that although the thing returned by fixture_file_upload has a @tempfile member, it lacks the reader method. Solved as follows

  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:


I went around this way

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



回答3:


I made a pull request to fix this issue, please +1 if you like it: https://github.com/brynary/rack-test/pull/67



来源:https://stackoverflow.com/questions/7793510/mocking-file-uploads-in-rails-3-1-controller-tests

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!