Rails モデルの RSpec 単体テストで validation と DB に対するテストを区別した

モデルの単体テストで validation と DB に対するテストで、describe ブロックを区別して書くように修正しました。

スポンサーリンク

— 環境 —
rails-4.0.1
rspec-rails-2.14.0
capybara-2.2.0

以下の記事を読んだのがきっかけです。

それでは,ActiveRecord モデルの,どこの何をテストすればよいのでしょうか.先に答えを言ってしまうと,どこをテストするのかについては
・Validation
・データベース
です.

データベースに関するテストでは,
制約テスト
・CHECK
・NOT NULL
・UNIQUE
参照整合性テスト
・FOREIGN KEY
を行ないます.

テストの書き方は超勉強中なので、こういう実践的な記事はとてもありがたい。これまで、validation と DB に対するテストは意識して書くようにしていて、それが正解なのを確認できたのは良かったです。しかし、両者のテストコードがごちゃ混ぜになっており、頭が混乱しがちでした。

describe ブロックを validation と DB で分けた

モデルの単体テスト(spec/models/user_spec.rb)で、validation に対するテストと DB に対するテストで describe ブロックを分けました。これで随分と見通しが良くなった。

spec/models/user_spec.rb

validation を RSpec でテスト

元記事は、Test::Unit を使われていますが、私は RSpec を使っているので、validation が invalid な場合に対する各々の具体的なテストは以下のように書く。

例えば、uid 属性が presence: true の validation なら以下。

uid が空の場合、it { should_not be_valid } で、@user が正当でないとテストできます。

データベースの例外発生を RSpec でテスト

再び引用。DB に対するテストについてです。

データベースに対するネガティブテストではデータベース例外の発生を確認します.具体的には,
・ActiveRecord::StatementInvalid … NOT NULL, CHECK 制約違反
・ActiveRecord::RecordNotUnique … UNIQUE 制約違反
・ActiveRecord::InvalidForeignKey … FOREIGN KEY 制約違反
が発生することを確認します.

RSpec で例外発生をテストするのは次の書き方を使う。

または、

例えば DB の email カラムに unique 制約が付いているのをテストする場合は以下。

既存のユーザーと email が同一のユーザーをレコードに保存しようとしたら、ActiveRecord::RecordNotUnique の例外が発生することを意図したテストです。

テストは何よりも読みやすさが大事なので、以上気を付けて書いていきたい。

スポンサーリンク
私は Rails のテストフレームワークには RSpec を使っています。サーバーのテスト用に Serverspec もおすすめです。
スポンサーリンク
 
Twitterを使っていますのでフォローお願いたします!ブログの更新情報もつぶやいてます^^
(英語学習用)

Leave Your Message!