19

Below is my testing code for uploading file.

describe "file process" do
 before(:each) do
   # debugger
   @file = fixture_file_upload('test.csv', 'text/csv')
 end

 it "should be able to upload file" do
  post :upload_csv, :upload => @file
  response.should be_success
 end
end

However, when I run rspec spec, it produced me the error below

Failure/Error: @file = fixture_file_upload('test.csv', 'text/csv')
 RuntimeError:
   test.csv file does not exist
 # ./spec/controllers/quotation_controller_spec.rb:29:in `block (3 levels) in <top (required)>'

I have googled alot of places but I still couldn't find out what's the reason behind it. Any idea?

Han Chee
  • 191
  • 1
  • 1
  • 6
  • 8
    Found one solution from SO [http://stackoverflow.com/questions/3966263/attachment-fu-testing-in-rails-3](http://stackoverflow.com/questions/3966263/attachment-fu-testing-in-rails-3). Apparently, I have to replace fixture_file_upload with this line `@file = Rack::Test::UploadedFile.new(Rails.root.join('spec/fixtures/test.csv'), 'text/csv')` – Han Chee Jan 26 '12 at 10:02
  • fixture_file_upload not working with Rails 3.1? – Han Chee Jan 26 '12 at 10:08
  • 1
    I started seeing this after we upgraded to 3.2 – plainjimbo Feb 06 '12 at 18:52
  • 1
    it seems it's broken in rails 3.2, check this issue on github: https://github.com/rspec/rspec-rails/issues/252 – Andrea Pavoni Feb 10 '12 at 14:20

3 Answers3

30

Fixture_file_upload basically still works. You just need to make sure the fixtures path in your spec_helper.rb file is uncommented & correctly set to the spec/fixtures path & to include ActionDispath::TestProcess:

RSpec.configure do |config|
  config.include ActionDispatch::TestProcess

  # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
  config.fixture_path = "#{::Rails.root}/spec/fixtures"

  ...

And where you are specifying the file in your tests, be sure to precede your file name with '/' like the following example:

describe "POST /subscriber_imports" do
  let(:file) { { :file => fixture_file_upload('/files/data.csv', 'text/csv') } }
  subject { post :create, :subscriber_import => file }
  ...
end

The absolute path to the file is the base path specified in config.fixture_path plus the relative path specified in fixture_file_upload function call. So, in this example, file.csv must be placed in #{::Rails.root}/spec/fixtures/files/data.csv

evedovelli
  • 2,115
  • 28
  • 28
Adrian Teh
  • 1,929
  • 18
  • 15
  • 3
    Also note the `include ActionDispatch::TestProcess`. This in particular fixed the issue for me – FeifanZ Oct 06 '15 at 16:49
  • `include ActionDispatch::TestProcess` is what fixed it for me as well. The odd part is that we had used `fixture_file_upload` fine in other rspec tests, but it failed for a new one. May have been that this new spec was scoped in a module. – zzz Dec 18 '17 at 18:10
4

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: {
      company: {
        logo: 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.

thisismydesign
  • 21,553
  • 9
  • 123
  • 126
  • fixture_file_upload is Shortcut for Rack::Test::UploadedFile.new(File.join(ActionDispatch::IntegrationTest.file_fixture_path, path), type) – alex Nov 02 '21 at 14:56
1

Based on the most voted answer on this question, you have to put the file under {Rails.root}/spec/fixtures/files

Community
  • 1
  • 1
hectorsq
  • 74,396
  • 19
  • 43
  • 46