unoh.github.com

railsのテストをevalを駆使して楽しよう

Sun Jun 24 09:57:18 -0700 2007

こんにちは satoです。

 testコードではパフォーマンスやセキュリティをさほど気にすることはないと思うので、testコードで evalを使って楽できるケースを書いてみたいと思います。

  よく似たModel で Userと Admin があるとします。 二つの Model には confirm というメソッドが定義されていて、ユーザ登録をしてメールで送られてくる URLを をクリックすると status が 'register' から 'confirm' に変更されます。

  class UserTest < Test::Unit::TestCase
    def test_with_confirm
      user = User.find(:first, :conditions => ["status = ?", 'register'])
      user.confirm
      assert(user.status == 'confirm', 'confirm error')
    end
  end


というテストをUserTest と AdminTest に書きます。

しかし以下のような moduleを継承しておくと DRYに書けます

  module UserModelTestHelper
    def get_class
      k = self.class.to_s.gsub(/Test$/, '')
      eval k
    end
    def test_with_confirm
      user = get_class.find(:first, :conditions => ["status = ?", 'register'])
      user.confirm
      assert(user.status == 'confirm', 'confirm error')
    end
  end


このようなクラスを定義しておくと module を incude するだけで 勝手にテストが生成されます。

  class TestUser < Test::Unit::TestCase
    include UserModelTestHelper 
  end
  class TestAdmin < Test::Unit::TestCase
    include UserModelTestHelper
  end


 同じような 共通のテストは UserModelTestHelperにどんどん追加するだけです。

 上記の例では クラス名を evalで Modelに変換していますが、テストファイル名やメソッド名を利用すると同じように楽できるケースがあると思います。。またUnitテストだけではなく Rspecなどにも普通に使えるのでNiceな方法を思いついたらぜひ教えてください