はじめに
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
変更点は、let
をlet!
としたところです。
let
のままだとexampleの中で作られるオブジェクトは、article
だけです。
なぜかというと、let
ではそのオブジェクトがexampleの中に出てくるときにのみオブジェクトが作成されるからです。
というわけで、このような例ではlet!
を使うといいですね!
Comments
Let's comment your feelings that are more than good