undefined method `file_fixture_path' after upgrade to ruby 3 and rails 6.1

Viewed 4939

After upgrade to ruby 3 and rails 6.1 my tests break on the line

subject.avatar.attach(fixture_file_upload(Rails.root.join('spec', 'fixtures', 'images', 'avatar.jpg')))

with:

NoMethodError:
        undefined method `file_fixture_path' for RSpec::Rails::FixtureFileUploadSupport::RailsFixtureFileWrapper:Class
        Did you mean?  fixture_path

the error stack points to webmock-3.11.0/lib/webmock/rspec.rb:37

Any suggestions how to debug it?

5 Answers

Ran into the same error, but had to solve it differently as the post in a request spec doesn't accept the object returned by file_fixture.

Including include ActionDispatch::TestProcess::FixtureFile in my request solved it for me.

RSpec.describe "Attachments", type: :request do
  include Rack::Test::Methods
  include ActionDispatch::TestProcess::FixtureFile
  #...
    expect {
      file = fixture_file_upload("image.jpg", "image/jpeg", :binary)
      post collection_work_attachments_path(collection, work), {attachment: {file: file, name: image_name, visibility: [:admin]}}
    }.to change(Attachment, :count).by(1)
  #...
end

Anything above didn't worked for me, but I found another solution.

In the factory changed this:

photo { fixture_file_upload(Rails.root.join('spec/support/images/test_image.png'), 'image/png') }

to this:

photo { Rack::Test::UploadedFile.new('spec/support/images/test_image.png', 'image/png') }

But after that I faced with another error:

unknown attribute 'service_name' for ActiveStorage::Blob

And solved this with two commands:

rails active_storage:update
rails db:migrate

I hope this may be useful to anybody.

Adding the following initializer addresses the issue without potential side-effects of including the ActionDispatch::TestProcess::FixtureFile module.

# config/initializers/rspec.rb

module RSpec
  module Rails
    module FixtureFileUploadSupport
      class RailsFixtureFileWrapper
        class << self
          attr_accessor :file_fixture_path
        end
      end
    end
  end
end

This is how the issue is actually fixed by RSpec maintainers. As of the date of this post, the patch is not yet released.

I was having the same issue for a long time and kept landing on this SO answer. My problem was that in a lot of my specs, one of my FactoryBot factories was calling fixture_file_upload and nothing suggested here fixed the issue.

I went into the ActionDispatch code and found that in the ActionDispatch::TestProcess::FixtureFile module's fixture_file_upload method, the factory object was queried for its fixture_path attribute, which it doesn't have. This is why the answer by @murb will work if your fixture_file_upload is within a spec file, but not in a factory file. For me, the answer was to add the following code to spec/support/factory_bot.rb in my Rails project:

FactoryBot::SyntaxRunner.instance_eval do
  def fixture_path
    File.absolute_path('spec/fixtures/files')
  end

  def file_fixture_path
    'spec/fixtures/files'
  end
end

Note that the second method (file_fixture_path) is to silence the warning in ActionDispatch::TestProcess::FixtureFile#fixture_file_upload.

I hope this helps someone, took me and another engineer a couple of days to land on this solution.

After changing to file_fixture it works just fine relishapp.com/rspec/rspec-rails/v/3-8/docs/file-fixture

Related