[Ruby] Unit test under Active Storage

2 minute read

What is Active Storage?

It is a function to upload files, If you use this, you can easily create an image posting function with a form. You can also upload files to cloud storage services You can do it easily.

In the case of myself, I was creating an application that has a function to upload images, so I had introduced Active Storage. The feature is that it is not necessary to prepare a column for images. This time, this feature was causing a lot of errors, but…

About the main test

The cause of this error is (1) FactoryBot created dummy image data'' (2) did not use the fixture_file_upload method in spec.rb``

The above two were causing errors mainly.

Especially with regard to ②, I was not able to arrive at all because I was just investigating misplacement.


Then from ①.

For example, if you have a model/table called product

If you are not using Active Storage Requires image column (column for images)

If you are using Active Storage No need for an image column (column for images)

That’s right.

Based on the above, if you review the description of FactoryBot

If you are not using Active Storage

products.rb


FactoryBot.define do
  factory :product do
    image {'test_image.jpg'}
    name {'lotion'}
    explanation {'Good lotion'}
    price {'2000'}
    user
  end
end

When using Active Storage

products.rb


FactoryBot.define do
  factory :product do
    name {'lotion'}
    explanation {'Good lotion'}
    price {'2000'}
    user
  end
end

This is natural. Because under Active Storage environment, image column is not necessary. (I didn’t realize at all…)

With this, the part of ① is solved.


Then turn to ②.

fixture_file_upload method

fixture_file_upload method

fixture_file_upload method

I said it three times because it is important. This method is provided by RSpec.

Spec.rb when the test did not pass at all ↓↓↓↓

product_spec.rb


require'rails_helper'


describe Product do

  describe'#create' do
    before do
      @product = build(:product)
    end


    
# 1. You can register if the image exists
    it'is valid with an image' do
      expect(@product).to be_valid
    end

# 2. Cannot register if name is empty
    it'is invalid without a name' do
      @product.name = nil
      @product.valid?
      expect(@product.errors[:name]).to include('Please enter')
    end

                        .
                        .
                        .
                        .
                        .

  end
end

Modified spec.rb ↓↓↓↓

product_spec.rb


require'rails_helper'


describe Product do

  describe'#create' do
    before do
      @product = build(:item)
      @product.image = fixture_file_upload("/files/test_image.jpg")
    end


    
# 1. You can register if the image exists
    it'is valid with an image' do
      expect(@product).to be_valid
    end

# 2. Cannot register if name is empty
    it'is invalid without a name' do
      @product.name = nil
      @product.valid?
      expect(@product.errors[:name]).to include('Please enter')
    end

                        .
                        .
                        .
                        .
                        .

  end
end

fixture_file_upload("/files/test_image.jpg") I mean that, but Test images are placed in the following directory.

spec
  ├ factories
  ├ fixtures
  │ └ files
  │ ├ test_image.jpg
  │ └ .keep
  ├ models
  :
  :

Call back (reserve) this between before do and end, We are generating a test image before the test code is executed.

With this, ② is also safely resolved.


If it solved it, it was a strange cause, It took a considerable amount of time and energy to get there.

I need to improve my search power…

I hope it will be useful for those who cannot pass the test due to the same reason.