はじめに
以下モデルのdeleteメソッドのspecを書いていて、なぜか空を判定してしまっていました。
モデル
class PearentModel < ApplicationRecord
has_many :child_model, dependent: :destroy
default_scope { where(is_deleted: false) }
# テスト対象
def delete
略(子モデルのis_deletedをtrueに更新する処理)
end
end
class ChildModel < ApplicationRecord
belongs_to :parent_model
default_scope { where(is_deleted: false) }
end
修正前のRspec
expect(parent_model.child_model.all? { |child| child.is_deleted }).to be_truethy
parent_model.child_model
が空でした。
原因と解決方法
テスト対象のメソッドはis_deletedをtrueに更新する処理であるため、 default_scope { where(is_deleted: false) }
によってレコードを取得できていませんでした。
unscope
を使うことでdefault_scopeを無視してレコードを取得し、is_deletedがtrueに更新されていることをテストするようにしました。
修正後のRspec
expect(parent_model.child_model.unscope.all? { |child| child.is_deleted }).to be truethy
おわりに
テストデータの関連付けがうまくいっていないものだと思い込み、数時間溶かしてしまったので供養しておきます。
空に対して.all?
を実行するとtrueが返ってくるので、テスト対象が空になっていないことを確認しておかないといけないですね。