まずActive Storageって何?
ファイルアップロードを行うための機能で、
これを使えばフォームで画像の投稿機能などが簡単に作れる。
また、クラウドストレージサービスへのファイルのアップロードも
簡単にできちゃいます。
自分の場合は画像をアップロードできる機能があるアプリケーションを作成していたので、
Active Storageを導入していました。
特徴としては画像用のカラムを用意する必要がないこと。
今回はこの特徴で、エラーがでまくっていたのですが...
##本題のテストのこと
今回のエラーの原因は
①FactoryBotで、ダミーのimageデータを作ってしまっていた
②spec.rbで、fixture_file_uploadメソッドを使っていなかった
以上の2つが主な原因でエラーを吐きまくっていました。
特に②に関しては、見当違いのことを調べていたばかりに中々たどり着きませんでした..
それでは①から。
例えばproductというモデル/テーブルがあるとして
Active Storageを使っていない場合
imageカラム(画像用のカラム)が必要
Active Storageを使っている場合
imageカラム(画像用のカラム)が必要ない
ですよね。
上記を踏まえてFactoryBotの記述を見直すと
Active Storageを使っていない場合
FactoryBot.define do
factory :product do
image { 'test_image.jpg' }
name { '化粧水' }
explanation { '良い化粧水です' }
price { '2000' }
user
end
end
Active Storageを使ってる場合
FactoryBot.define do
factory :product do
name { '化粧水' }
explanation { '良い化粧水です' }
price { '2000' }
user
end
end
こうなるのは当然ですよね。
だってActive Storage環境下ではimageカラム必要ないですし。
(全然気付いていなかった..)
これで①の部分は解決しました。
###fixture_file_uploadメソッド
続いて②の方を。
このメソッドはRSpecで用意されているメソッドです。
全然テストが通らなかったときのspec.rb ↓↓↓↓
require 'rails_helper'
describe Product do
describe '#create' do
before do
@product = build(:product)
end
# 1. imageが存在すれば登録できること
it 'is valid with an image' do
expect(@product).to be_valid
end
# 2. nameが空では登録できないこと
it 'is invalid without a name' do
@product.name = nil
@product.valid?
expect(@product.errors[:name]).to include('を入力してください')
end
.
.
.
.
.
end
end
修正後の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. imageが存在すれば登録できること
it 'is valid with an image' do
expect(@product).to be_valid
end
# 2. nameが空では登録できないこと
it 'is invalid without a name' do
@product.name = nil
@product.valid?
expect(@product.errors[:name]).to include('を入力してください')
end
.
.
.
.
.
end
end
fixture_file_upload("/files/test_image.jpg")
とはなんぞやということなんですけども、
下記のディレクトリの通りにテスト画像を配置しています。
spec
├ factories
├ fixtures
│ └ files
│ ├ test_image.jpg
│ └ .keep
├ models
:
:
これを、before do ~ end の間でコールバック(予約)しておいて、
テストコードが実行される前にテスト用の画像を生成しているわけです。
これで②も無事に解決です。
解決してしまえばなんてことない原因でしたが、
たどり着くまでに相当な時間と気力を消費してしまいました。
もっと検索力上げないとな...
同じような原因でテストが通らない方の参考になれば幸いです。