テスト用インスタンス生成ヘルパー
ふと思った
テストの際に、invalidなインスタンスを作成したり、検索テスト用に、対象カラムだけの値を変えたようなインスタンス/レコードを作成することが多い。
その際に、全てのカラムを指定するのが面倒だったりする。特に、validate_presence_ofとかの検証をかけていると、その部分のカラムも指定してやらないとcreateできない。そこで、こんなヘルパーを作ってみた。
- test_helper.rb
def create_new_record(klass,default,options = {},*nil_on_new_record) if options.keys.include?(:all) attrs = klass.column_names.inject({}){|h,k| h.merge(k => options[:all])} else nil_on_new_record = nil_on_new_record | [:id, :created_at, :updated_at] attrs = default.attributes.reject{|k,v| nil_on_new_record.include?(k.to_sym)} attrs.merge!(options) end klass.new(attrs) end
呼び出し側はこんな感じ。
class UserTest < Test::Units::TestCase fixtures :users def test_validates_presence_of user = new_record(:all => nil) assert !user.valid? assert user.errors.invalid?(:name) assert user.errors.invalid?(:address) end def test_validates_length_of too_long_name = "abcdeabcdeabcdeabcdea" #maximum => 20 user = new_record(:name => too_long_name) assert !user.valid? assert user.errors.invalid?(:name) end private def new_record(options = {}) create_new_record(User,@bob,options) end end
- users.yml
bob: id: 1 name: bob address: bob@address.com created_at: <%= 2.day.ago.to_formatted_s(:db)%> updated_at: <%= 1.day.ago.to_formatted_s(:db)%>
このnew_recordメソッドを各テスト用のクラスに実装する。(冗長かな?)
- create_new_record:対象のクラス
- default:土台レコード。fixtureのデータを渡すとよい。optionsでこの値の一部を変更してインスタンスを生成する
- options:上書きする値を指定。:allを指定すると、全てのカラムがその値のインスタンスができる。(専ら:all => nilで使用)
- nil_on_new_record::new_record => trueのインスタンスでは値が入らない。idは典型。fixtureではidとかが入ってしまっているのでそれを排除する。
インスタンスを生成するのに関数型っぽいのがなんかな・・・