开发者

Rails Functional Test Case and Uploading Files to ActionDispatch::Http::UploadFile

I'm am adding tests to a Rails app that remotely stores files. I'm using the default Rails functional tests. How can I add file uploads to them? I have:

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

This for some reason uploads a Tempfile and causes the AWS/S3 gem to fail with:

NoM开发者_运维问答ethodError: undefined method `bytesize' for Tempfile

Is their any way that I can get the test to use an ActionDispatch::Http::UploadedFile and perform more like it does when testing with the web browser? Is fixture_file_upload the way to test uploading files to a controller? If so why doesn't it work like the browser?

As a note, I really don't want to switch testing frameworks. Thanks!


I use the s3 gem instead of the aws/s3 gem. The main reasons for this are no support for european buckets and development of aws/s3 seems to be stopped.

If you want to test file upload than using the fixtures_file_upload method is correct, it maps directly to Rack::Test::UploadedFile.new (you can use this if the test file isn't in the fixtures folder).

But I've also noticed that the behavior of the Rack::Test::Uploaded file objects isn't exactly the same as the ActionDispatch::Http::UploadedFile object (that's the class of uploaded files). The basic methods (original_filename, read, size, ...) all work but there are some differences when working with the file method. So limit your controller to these methods and all will be fine.

An other possible solution is by creating an ActionDispatch::Http::Uploaded file object and using that so:

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 }


I'd recommend using mocks. A quick google search reveals:

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

You should be able to create an object that will respond to the behaviors you want it to. Mostly used in a Unit test environment, so you can test your stuff in isolation, as integration tests are supposed to fully exercise the entire stack. However, I can see in this case it'd be useful to mock out the S3 service because it costs money.


I'm not familiar with the AWS/S3 gem, but it seems that you probably aren't using the :avatar param properly. bytesize is defined on String in ruby1.9. What happens if you call read on the uploaded file where you pass it into AWS/S3?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜