fpietka
fpietka

Reputation: 1043

Can't use a model using CarrierWave without a real file in Rails using rspec

I'm trying to run a test using a model, but I'm trying not to have to use a file for real here.

My use case is in rspec I try to create that object with a property handled by CarrierWave using FactoryBot, but I don't know what to pass to my icon property except a real file.

My model is like this:

class MyItem < ApplicationRecord
  validates :icon, presence: true

  mount_uploader :icon, MyIconUploader
end

Using FactoryBot, when I try to run create I have this error:

     ActiveRecord::RecordInvalid:
       Validation failed: Icon can't be blank

Only thing that works seems to be the following:

FactoryBot.define do
  factory :item, class: 'MyItem' do
    icon { Rack::Test::UploadedFile.new(File.join(Rails.root, 'spec', 'assets', 'images', 'image.jpg')) }
  end
end

Giving it a file from memory would also work for me, as long as it is not a physical one.

Upvotes: 1

Views: 344

Answers (1)

mikezter
mikezter

Reputation: 2463

You can use StringIO class for that. Since CarrierWave also expects a filename on the given IO object, you would also need to subclass StringIO to something like this:

class StringIOWithName < StringIO
  def initialize(stream, filename)
    super(stream)
    @original_filename = filename
  end

  attr_reader :original_filename
end

Then you can give an instance of StringIOWithName to Carrierwave.

Upvotes: 2

Related Questions