mo-fu note

研究からキックボクシングまで何でも書いていきます!

Railsでデータベースのユニットテスト

Railsのモデルでバリデーションしているけど、 データベース側の制約を使っていなくて、不正なデータが登録されてしまう事がある。 バリデーションだけでなく、データベースの機能を使って不正なデータの登録を防がないといけない。

例えば、以下のような時に不正なデータが登録される可能性がある。

  • アプリケーションのバグ
  • 手動作業によるデータの登録・更新
  • 他のアプリケーションからデータベースを利用

データベースの機能を使っていろんな制約を付けられるけど、 今回はusersテーブルのemailカラムにUNIQUE制約をつけた時に、その機構が正しく動くかチェックするテストをしてみた。

データベースのユニットテストって感じなのかな。

実行環境

  • Ruby 2.2.2
  • Rails 4.2.3
  • RSpec 3.3
  • factory_girl 4.5.0
  • sqlite3 1.3.10

Userモデル

class User < ActiveRecord::Base
  validates :email, uniqueness: true
end

テストコード

RSpec.describe User, :type => :model do
  describe 'email uniqueness' do
    before do
      FactoryGirl.create(:user, email: 'foo@example.com')
      @user = FactoryGirl.build(:user, email: 'foo@example.com')
    end

    it 'returns false with uniqueness validation' do
      expect(@user.save).to be_falsey
    end

    # foo@example.com は既に登録されているので例外が発生する
    it 'raise error with a unique constraint' do
      expect do
        @user.save(validate: false)
      end.to raise_error(ActiveRecord::RecordNotUnique)
    end
  end
end

UNIQUE制約つけていなかった場合はmigrationファイルでこんな感じに書いて rake db:migrate する

class AddIndexEmailToUsers < ActiveRecord::Migration
  def change
    add_index :users, :email, unique: true
  end
end

自分1人で運用している趣味のRailsアプリケーションとは違って、 ビジネス用のアプリケーションとしてRailsを活用している場合は、 不正なデータが登録されないように注意深く実装していかないと、 後々変なデータが出てきた時に、その「データの修正」にはとどまらないコストが発生するかもしれない。

エンタープライズ Rails ―企業ユーザのためのWebアプリケーション設計術

エンタープライズ Rails ―企業ユーザのためのWebアプリケーション設計術

  • 作者: Dan Chak,高井直人,笹井崇司
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2009/07/23
  • メディア: 単行本(ソフトカバー)
  • 購入: 36人 クリック: 751回
  • この商品を含むブログ (17件) を見る

色々気になってきたのでエンタープライズ Rails購入した。

参考サイト