Search code examples
rubyunit-testingruby-on-rails-5rspec-railsrails-activestorage

Upload image with RSpec has unexpected class on controller


I'm in trouble with RSpec and fixture_file_upload on post request.

Here's the problem: I'm trying to send an image by upload to create a category with image, but when the image arrives, it changes it's class type.

I'm waiting to get in params[:category][:image] an ActionDispatch::Http::UploadedFile but what I receive is ActionController::Parameters.

My request example:

    context 'when creates a new main category with valid params' do
      let(:category) do
        { category: { name: 'Bolos E bolos',
                      description: 'São bolos sim',
                      locale: 'pt-BR',
                      image: fixture_file_upload('images/test-image.png', 'image/png') } }
      end

      post '/v4/categories' do
        it 'upload image' do
          expect { do_request(category) }.to change { ActiveStorage::Blob.count }.from(0).to(1)
        end
      end
    end

what I got:

Failure/Error: expect { do_request(category) }.to change { ActiveStorage::Blob.count }.by(1)
       expected `ActiveStorage::Blob.count` to have changed by 1, but was changed by 0 

How do I send the image as upload and get it on the controller as ActionDispatch::Http::UploadedFile instead ActionController::Parameters


Solution

  • I could not get your controller spec working, but I managed to get an equivalent request spec working. Having spent 45+ minutes getting no where, I think this is the best I can do. This seems to work. (Just make sure you have an avatar.jpg in the public folder of your rails app.)

    ## spec/requests/user_spec.rb
    require 'rails_helper'
    
    RSpec.describe "Users", type: :request do
    
      describe "it attaches uploaded files" do
        it 'attaches the uploaded file' do
          file = fixture_file_upload(Rails.root.join('public', 'avatar.jpg'), 'image/jpg')
          expect {
            post api_users_path, params: { user: {username: "Ben", avatar: file } }
          }.to change(ActiveStorage::Attachment, :count).by(1)
        end
      end
    end