Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 414
mingle Avatar asked Jan 09 '21 09:01

mingle


4 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
like image 164
murb Avatar answered Oct 13 '22 11:10

murb


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.

like image 22
Ruslan Valeev Avatar answered Oct 13 '22 09:10

Ruslan Valeev


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.

like image 3
Alexander Makarenko Avatar answered Oct 13 '22 09:10

Alexander Makarenko


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.

like image 1
ewhiting Avatar answered Oct 13 '22 11:10

ewhiting