Search code examples
ruby-on-railsrspecrspec-railsruby-on-rails-6rails-activestorage

Rails ActiveStorage is attached? true, but not in rspec expection


I wanna test an action which attaches an image. I use a rSpec request spec. The image gets attached in real requests, but the rspec fails Why?

  def update_logo
    if params[:logo].present?
      image = params[:logo]
      if image && @current_user.logo.attach(image)
        puts @current_user.logo.attached? # !!! results in TRUE !!!
        render json: @current_user, status: :ok
      end
    end
  end


  it "attaches a logo" do
    post update_logo_url,
      params: { logo: fixture_file_upload(file_fixture('400x400.png'), 'image/png') },
                headers: { "Authorization" => token_generator(user.id) }
     expect(user.logo).to be_attached
   end

expected `#<ActiveStorage::Attached::One:0x00007fb9f57a90e8 @name="logo", @record=#<User id: 1, name: "....210787000 +0000">>.attached?` to be truthy, got false

BTW:

Other tests like ActiveStorage::Attachment.count works So, this is "green":

      it 'saves the uploaded file' do
        expect {
          subject
        }.to change(ActiveStorage::Attachment, :count).by(1)
      end

Solution

  • Try reloading the user instance before checking the attachment:

    expect(user.reload.logo).to be_attached
    # ----------^^^^^^
    

    You're pulling the user out of the database before the request is made. Then the controller method will create its own instance, add the attachment, and save everything. But the user in your test won't know about any of that. If you user.reload, user will be refreshed with the latest information from the database and user.logo should be attached.