検索結果のテスト assert_found

railsでテストコードを書いている際に、次のようなコードが多くあった。

assert_equal [1, 2, 3], assigns(:users).map(&:id)
result = User.find(:all, :conditions => ["school = ?", "Hoge"])
assert_equal [2, 3], result.map(&:id)

面倒だ

なので、Array#fuzzy_equal?を使って次のように実装。

def assert_found(expecteds, *options)
  if block_given?
    actual = yield
  else
    actual = options.first
  end 

  if options.last.is_a?(Hash) && options.last[:ordered]
    assert_equal expecteds, actual.map(&:id)
  else
    assert expecteds.fuzzy_equal?(actual.map(&:id))
  end
end


こんな感じで使う。

assert_found [1, 2, 3], assigns(:users), :ordered => true
assert_found [3, 2, 1], assigns(:users)
assert_found [2, 3] do
  User.find(:all, :conditions => ["school = ?", "Hoge"])
end


なんか、optionsが微妙だ。assert_found(expected, actual = nil, options = {})とやると、optionsを指定する際には第2引数が必須になるからな。うーん