【Rails】rspecでmodelのconcernを単体テストする方法
ことの始まり
結構大きめの複数modelで使うメソッドを作る必要があったから、concernにまとめちゃおうと思ったものの、メソッドの単体テストどうしよう…
ということで、調べたら一応できた。
最近rspec周りの記事が多いなぁ
modelのconcern作成
例えばuser model
があり、first_name
とlast_name
をテーブルに持っているとする。
class User < ApplicationRecord # == Schema Information # # Table name: users # # id :integer # first_name :string # last_name :string end
first_name
とlast_name
を別々に保存はしたいものの、実際に出力する際は一緒にしたfull_name
を使いたい。
他のmodel
でも使うことがありそうだから、concern
に切り分けておく。
module FullNameCreator extend ActiveSupport::Concern private def full_name(str_1:, str_2:) "#{str_1} #{str_2}" # 半角スペースを入れたnameを返す end end
作ったconcern
をmodel
で使う。
class User < ApplicationRecord include FullNameCreator def name full_name(str_1: first_name, str_2: last_name) end end
これで、他のクラス(例えばCustomer model
とか)でも作成したconcern
を使うことができるようになる。
concernの単体テスト
rspecでconcern
のメソッドが期待値通りの動きをしているかの確認をするには、User model
のテストでname
メソッドが期待値を返しているかで確認をすることもできるが、他のmodel
でも確認が必要になる。
複数model
で使っていると面倒なので、concern
で単体テストを実行したい。
分けて書くのは面倒なのでコメントアウトで解説を入れながらコードを書いてみる。
require 'rails_helper' require 'spec_helper' RSpec.describe FullNameCreator, type: :model do # 今回確認したいメソッド describe '.full_name' do # まずはテストに必要なテーブルを作成する before(:all) do m = ActiveRecord::Migration.new m.verbose = false m.create_table :full_name_tests do |t| t.string :first_name t.string :last_name end end # テストが終わったらテーブルを削除 after(:all) do m = ActiveRecord::Migration.new m.verbose = false m.drop_table :full_name_tests end # テスト用のモデルを作成(対象のconcernをincludeしておく) class FullNameTest < ApplicationRecord include FullNameCreator end # テスト用のクラスを作成(入力値は後で指定するのでインスタンス変数にしておく) let(:user) { FullNameTest.new(first_name: first_str, last_name: second_str) } # 作成したクラスをテスト用に保存 before {user.save} # テストしたいメソッドをsubjectにする(引数はメソッド名に続けて記載しておく) subject { user.send(:full_name, str_1: first_str, str_2: second_str) } context 'return full name' do # 先ほど使ったインスタンス変数に代入 let(:first_str) { "yasa" } let(:second_str) { "gori" } it { is_expected.to eq("yasa gori") } end end end
これで、concern
の単体テストができる。
今回はメソッドが1つしかないのでメソッドの中でテーブルを作成したが、複数のメソッドを確認する場合は各メソッドごとにテーブルをcreate, dropすると時間がかかるので、まとめてやった方が良い。
まとめ
concern
の単体テストは下準備が非常に多いので実際やる思った以上に面倒だった…