2015/12/16

assert_change

ユニットテスト時によく使うメソッドの1つに assert_difference がありますね。
でもこれ差分を取るので数値を返す式にしか使えません。使おうとしたら + なんて演算子ないよってエラーが出ます。
仕方なしにこんなテストコードを書いてません?
test 'ユーザーが確認済みになること' do
  assert_not user.confirmed?
  # ここに承認処理
  assert user.confirm?
end
それならば、こんなメソッドを test_helper あたりに定義しておいて
def assert_change(expression, message = nil, &block)
exp = expression.respond_to?(:call) ? expression : ->{ eval(expression, block.binding) }
before = exp.call
yield
error = "#{expression.inspect} didn't change"
error = "#{message}.\n#{error}" if message
assert_not_equal before, exp.call, error
end
def assert_not_change(expression, message = nil, &block)
exp = expression.respond_to?(:call) ? expression : ->{ eval(expression, block.binding) }
before = exp.call
yield
error = "#{expression.inspect} changed"
error = "#{message}.\n#{error}" if message
assert_equal before, exp.call, error
end
test 'ユーザーが確認済みになること' do
  assert_change 'user.confirmed?' do
    # ここに承認処理
  end
end

# 実際の値を気にしなくていいならこんな使い方も
test '保存したら updated_at が更新される' do
  assert_change 'user.updated_at' do
    user.save
  end
end
と書くとちょっとスッキリしますね。コードはほぼほぼ assert_difference のパクリです。
expression の指定方法は必要になったら広げる感じでいいかな。

0 件のコメント :

コメントを投稿