I want to test a file upload in rails, but am not sure how to do this.
Here is the controller code:
def uploadLicense
#Create the license object
You can use fixture_file_upload method to test file uploading: Put your test file in "{Rails.root}/spec/fixtures/files" directory
before :each do
@file = fixture_file_upload('files/test_lic.xml', 'text/xml')
end
it "can upload a license" do
post :uploadLicense, :upload => @file
response.should be_success
end
In case you were expecting the file in the form of params['upload']['datafile']
it "can upload a license" do
file = Hash.new
file['datafile'] = @file
post :uploadLicense, :upload => file
response.should be_success
end
I am not sure if you can test file uploads using RSpec alone. Have you tried Capybara?
It's easy to test file uploads using capybara's attach_file
method from a request spec.
For example (this code is a demo only):
it "can upload a license" do
visit upload_license_path
attach_file "uploadLicense", /path/to/file/to/upload
click_button "Upload License"
end
it "can download an uploaded license" do
visit license_path
click_link "Download Uploaded License"
page.should have_content("Uploaded License")
end
This is how I did it with Rails 6
, RSpec
and Rack::Test::UploadedFile
describe 'POST /create' do
it 'responds with success' do
post :create, params: {
license: {
picture: Rack::Test::UploadedFile.new("#{Rails.root}/spec/fixtures/test-pic.png"),
name: 'test'
}
}
expect(response).to be_successful
end
end
DO NOT include ActionDispatch::TestProcess or any other code unless you're sure about what you're including.
I haven't done this using RSpec, but I do have a Test::Unit test that does something similar for uploading a photo. I set up the uploaded file as an instance of ActionDispatch::Http::UploadedFile, as follows:
test "should create photo" do
setup_file_upload
assert_difference('Photo.count') do
post :create, :photo => @photo.attributes
end
assert_redirected_to photo_path(assigns(:photo))
end
def setup_file_upload
test_photo = ActionDispatch::Http::UploadedFile.new({
:filename => 'test_photo_1.jpg',
:type => 'image/jpeg',
:tempfile => File.new("#{Rails.root}/test/fixtures/files/test_photo_1.jpg")
})
@photo = Photo.new(
:title => 'Uploaded photo',
:description => 'Uploaded photo description',
:filename => test_photo,
:public => true)
end
Something similar might work for you also.
I had to add both of these includes to get it working:
describe "my test set" do
include Rack::Test::Methods
include ActionDispatch::TestProcess
if you include Rack::Test*, simply include the test methods
describe "my test set" do
include Rack::Test::Methods
then you can use the UploadedFile method:
post "/upload/", "file" => Rack::Test::UploadedFile.new("path/to/file.ext", "mime/type")
*NOTE: My example is based on Sinatra, which extends Rack, but should work with Rails, which also uses Rack, TTBOMK