assert_change
at 2015-12-16 01:42 (UTC)
ユニットテスト時によく使うメソッドの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
の指定方法は必要になったら広げる感じでいいかな。