Last Updated: February 25, 2016
·
1.531K
· deteam

Rails UploadedFile testing

Sometimes you may want to pass a file/IO to params in your controller tests/specs.

Here fixturefileupload really comes to the rescue, but let's image that we want to reuse same File/CustomFile variable passed i.e. from before :each.

Fixtures won't help us with that: inside there's a Tempfile instance, which may be somehow closed after being used in your app logic.

Custom class (i.e. based on Rack::Test::UploadedFile with File and not Tempfile inside) would solve the issue, but it won't work unless you specify:

def to_param
    self
end

Here's where it comes from:
https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/test_case.rb#L458

def paramify_values(hash_or_array_or_value)
  case hash_or_array_or_value
  when Hash
    Hash[hash_or_array_or_value.map{|key, value| [key, paramify_values(value)] }]
  when Array
    hash_or_array_or_value.map {|i| paramify_values(i)}
  when Rack::Test::UploadedFile, ActionDispatch::Http::UploadedFile
    hash_or_array_or_value
  else
    hash_or_array_or_value.to_param
  end
end