Posted at

【Rails5】DBからデータが削除されたことをテスト自動化するときの観点たち


Introduction

Railsでデータを削除する機能をRSpecのSystem Testでテストしたときのメモ。

「削除対象のレコードが削除されていること」を確認するためにいくつかの観点から検証を実施してみました。


【観点1】対象を削除すると検索してもNotFound

[id=1のレコードを削除処理]

expect{Model.find(1)}.to raise_exception(ActiveRecord::RecordNotFound)

まずは素直に削除した対象を検索するとNotFoundになる検証。find_byを使っても同じように検証できます。

あんまり考えにくいですが、idupdateされた場合でも検証は通ってしまいます。

ちなみに今回の記事で一番メモしておきたかったのはこのraise_exceptionの書き方。

expect{}とブロックで記述しないといけないのがかなりつまずきポイントでした。


【観点2】対象を削除するとwhere検索しても0件

expect(Model.where(id: 1).count).to eq 1

[id=1のレコードを削除処理]
expect(Model.where(id: 1).count).to eq 0

次はwhereを使ってひっかかった数が0になることでレコードが削除されたことを検証する方法です。この場合でも、idupdateされたケースは検証は通ってしまいます。

whereなので1件に絞る必要はなく、例えばアソシエーションの全ての子要素を消す時の検証などでは使いやすい気がします。「User1に紐づく全Itemを削除」の場合はexpect(Item.where(user_id: 1).count).to eq 0とすれば検証ができます。

一方で、whereだとデータ量が多いとテスト実行の性能が悪くなったりするのかな。


【観点3】対象を削除するとレコード数が減る

count = Model.all.count

[いずれか1レコードを削除処理]
expect(Model.all.count).to eq (count - 1)

1レコード削除されれば総数が1減る、という検証です。これ単体では何が消えたのか定かではありませんが、観点1・2と合わせることで「idupdateされた」可能性をなきものとできる気がします。


Conclusion

【観点1】or【観点2】でおおよそやりたいことはできました。【観点3】も合わせ技として複合すれば、間違ってほかのレコードも消していないことなども検証できるので安心安全です。