はじめに
Next.js(フロントエンド)と Rails API(バックエンド)の構成で、ActiveStorageを使ったプロフィール画像のアップロード機能を実装しました。本記事では、その実装に対するテストコードの書き方を解説します。
User モデルのカスタマイズ
ActiveStorageの image 属性は、そのままJSONとして返すと複雑なオブジェクト構造になってしまい、フロントエンドで扱いにくくなります。そこで、以下の2つのメソッドを追加して、シンプルなURL文字列として返せるようにしています。
rails/app/models/user.rb
class User < ApplicationRecord
has_one_attached :image
# 画像のURLを取得(未アップロード時は nil)
def image_url
image.attached? ? Rails.application.routes.url_helpers.rails_blob_url(image) : nil
end
# JSONレスポンスをカスタマイズ
# imageオブジェクト → image_url(文字列)に変換
def as_json(options = {})
super(options.merge(except: :image)).merge(
"image_url" => image_url, # ← メソッドを呼び出す
)
end
end
User モデルのテストコード
Active Storage の動作とimage_urlメソッドが正しく機能するかを確認するテストを作成します。
rails/spec/models/user_spec.rb
require "rails_helper"
RSpec.describe User, type: :model do
context "image" do
let(:user) { create(:user) }
# テスト1: 画像の添付機能
it "画像を添付できる" do
user.image.attach(
io: Rails.root.join("spec", "fixtures", "test_image.webp").open,
filename: "test_image.webp",
content_type: "image/webp",
)
expect(user.image).to be_attached
end
# テスト2: image_urlメソッド(画像あり)
it "画像が添付されている場合、URLを返す" do
user.image.attach(
io: Rails.root.join("spec", "fixtures", "test_image.webp").open,
filename: "test_image.webp",
content_type: "image/webp",
)
# Active Storageが生成するURLには"blob"が含まれる
expect(user.image_url).to include("blob")
end
# テスト3: image_urlメソッド(画像なし)
it "画像が添付されていない場合、nilを返す" do
expect(user.image_url).to be_nil
end
end
end
ポイント:
-
user.image.attachで事前に配置したspec/fixtures内の画像ファイルを添付 -
be_attachedで添付状態を確認 -
image_urlが返す URL には ActiveStorage特有のblobという文字列が含まれる
参考