LoginSignup
2
1

More than 3 years have passed since last update.

ActiveModel::Serializerのテストでつまづいたこと

Posted at

はじめに

ActiveModel::SerializerのRspecでテストの書き方の例を挙げました。
ですが、他のSerializerのテストを書く時につまづいたことがあるので、投稿します。

ソースコード

今回の例は、ArticleとCategoryが多対多の関係にあり、article_category.rbという中間モデルを持っているとします。

article.rb
class Article < ApplicationRecord
  has_many :article_categories
  has_many :categories, through: :article_categories
end
article_serializer.rb
class ArticleSerializer < ActiveModel::Serializer
  attributes :id, :title
  has_many :categories
end

このSerializerのテストを書くとこんな感じ

article_serializer_spec.rb
require 'rails_helper'

RSpec.describe ArticleSerializer, type: :serializer do
  context "新たに記事が作成された時" do
    let(:article) { create(:article) }
    let(:category) { create(:category) }
    let(:article_category) do
      create(:article_category, category: category, article: article)
    end

    it "シリアライズされたJSONが作成されること" do
      serializer = ArticleSerializer.new(article)
      expect(serializer.to_json).to eq(article.to_json(:only => [:id, :title], :include => { :category })
    end
  end
end

テスト結果

テストしてみると、返却されたJSONにhas_many関係のcategoryが含まれておらず、空のままでした。なぜ、、、

解決方法

このテストの書き方が悪かったようで、このように書いたら通りました。

article_serializer_spec.rb
require 'rails_helper'

RSpec.describe ArticleSerializer, type: :serializer do
  context "新たに記事が作成された時" do
    let!(:article) { create(:article) }
    let!(:category) { create(:category) }
    let!(:article_category) do
      create(:article_category, category: category, article: article)
    end

    it "シリアライズされたJSONが作成されること" do
      serializer = ArticleSerializer.new(article)
      expect(serializer.to_json).to eq(article.to_json(:only => [:id, :title], :include => { :category })
    end
  end
end

変更点は、letlet!としたところです。
letのままだとexampleの中で作られるオブジェクトは、articleだけです。
なぜかというと、letではそのオブジェクトがexampleの中に出てくるときにのみオブジェクトが作成されるからです。

というわけで、このような例ではlet!を使うといいですね!

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1