😀
RSpecでDB制約のテストを書く場合のTips
TL;DR
- controller, serviceに対しての例外ロジックが増えてきたら、まずはmodelやdb制約を疑おう。
- データレベルで不正な値が入っていなければ、そもそもcontrollerやserviceで考慮すべきことは相当少なくなる。
- モデル側の単体テストで、DB制約時のテストを行おう
RSpecでDB制約のテストを書く場合
- validationのテストは、
save
での返り値をテストすればOK - 一方で、database constraintのテストは
save(validate: false)
オプションで、validationをスキップして保存が可能。 - これを利用することで、DB制約が起こるか確認できる
バリデーションだけ書けば良くね?
- そんなことはない。DBロジックを正しい前提にして、ビュー側で500エラーが出たりするケースが多い。
- バリデーションだけで弾いておいても、DB側に不正なデータが入るケースは全然あり得る。
- 本番環境で直接コンソールを叩いたりした場合
- Bulk Insertした場合
- 途中からvalidationは変更したけど、過去のデータが残っていて悪さをする場合
- モデル層でのvalidationは、意図する範囲での制限, DB層でのconstraintは意図しない範囲での制限
- なので極力モデルにもdbにも同じ制約をつけておく必要がある。
Discussion