Module: ActiveSupport::Testing::Assertions
- Included in:
- ActiveJob::TestHelper, ActiveSupport::TestCase
- Defined in:
- activesupport/lib/active_support/testing/assertions.rb
Constant Summary collapse
- UNTRACKED =
:nodoc:
Object.new
Instance Method Summary collapse
-
#assert_changes(expression, message = nil, from: UNTRACKED, to: UNTRACKED, &block) ⇒ Object
Assertion that the result of evaluating an expression is changed before and after invoking the passed in block.
-
#assert_difference(expression, *args, &block) ⇒ Object
Test numeric difference between the return value of an expression as a result of what is evaluated in the yielded block.
-
#assert_no_changes(expression, message = nil, from: UNTRACKED, &block) ⇒ Object
Assertion that the result of evaluating an expression is not changed before and after invoking the passed in block.
-
#assert_no_difference(expression, message = nil, &block) ⇒ Object
Assertion that the numeric result of evaluating an expression is not changed before and after invoking the passed in block.
-
#assert_not(object, message = nil) ⇒ Object
Asserts that an expression is not truthy.
-
#assert_nothing_raised ⇒ Object
Assertion that the block should not raise an exception.
-
#assert_raises(*exp, match: nil, &block) ⇒ Object
(also: #assert_raise)
Asserts that a block raises one of
exp
.
Instance Method Details
#assert_changes(expression, message = nil, from: UNTRACKED, to: UNTRACKED, &block) ⇒ Object
Assertion that the result of evaluating an expression is changed before and after invoking the passed in block.
assert_changes 'Status.all_good?' do
post :create, params: { status: { ok: false } }
end
You can pass the block as a string to be evaluated in the context of the block. A lambda can be passed for the block as well.
assert_changes -> { Status.all_good? } do
post :create, params: { status: { ok: false } }
end
The assertion is useful to test side effects. The passed block can be anything that can be converted to string with #to_s.
assert_changes :@object do
@object = 42
end
The keyword arguments :from
and :to
can be given to specify the expected initial value and the expected value after the block was executed. The comparison is done using case equality (===), which means you can specify patterns or classes:
# Exact value match
assert_changes :@object, from: nil, to: :foo do
@object = :foo
end
# Case equality
assert_changes -> { user.token }, to: /\w{32}/ do
user.generate_token
end
# Type check
assert_changes -> { current_error }, from: nil, to: RuntimeError do
raise "Oops"
end
An error message can be specified.
assert_changes -> { Status.all_good? }, 'Expected the status to be bad' do
post :create, params: { status: { incident: true } }
end
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 |
# File 'activesupport/lib/active_support/testing/assertions.rb', line 211 def assert_changes(expression, = nil, from: UNTRACKED, to: UNTRACKED, &block) exp = expression.respond_to?(:call) ? expression : -> { eval(expression.to_s, block.binding) } before = exp.call retval = _assert_nothing_raised_or_warn("assert_changes", &block) unless from == UNTRACKED = -> do error = "Expected change from #{from.inspect}, got #{before.inspect}" error = "#{}.\n#{error}" if error end assert from === before, end after = exp.call = -> do code_string = expression.respond_to?(:call) ? _callable_to_source_string(expression) : expression error = "`#{code_string}` didn't change" error = "#{error}. It was already #{to.inspect}" if before == to error = "#{}.\n#{error}" if error end refute_equal before, after, unless to == UNTRACKED = -> do error = "Expected change to #{to.inspect}, got #{after.inspect}\n" error = "#{}.\n#{error}" if error end assert to === after, end retval end |
#assert_difference(expression, *args, &block) ⇒ Object
Test numeric difference between the return value of an expression as a result of what is evaluated in the yielded block.
assert_difference 'Article.count' do
post :create, params: { article: {...} }
end
An arbitrary expression is passed in and evaluated.
assert_difference 'Article.last.comments(:reload).size' do
post :create, params: { comment: {...} }
end
An arbitrary positive or negative difference can be specified. The default is 1
.
assert_difference 'Article.count', -1 do
post :delete, params: { id: ... }
end
An array of expressions can be passed in and evaluated.
assert_difference [ 'Article.count', 'Post.count' ], 2 do
post :create, params: { article: {...} }
end
A hash of expressions/numeric differences can be passed in and evaluated.
assert_difference({ 'Article.count' => 1, 'Notification.count' => 2 }) do
post :create, params: { article: {...} }
end
A lambda, a list of lambdas or a hash of lambdas/numeric differences can be passed in and evaluated:
assert_difference ->{ Article.count }, 2 do
post :create, params: { article: {...} }
end
assert_difference [->{ Article.count }, ->{ Post.count }], 2 do
post :create, params: { article: {...} }
end
assert_difference ->{ Article.count } => 1, ->{ Notification.count } => 2 do
post :create, params: { article: {...} }
end
An error message can be specified.
assert_difference 'Article.count', -1, 'An Article should be destroyed' do
post :delete, params: { id: ... }
end
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'activesupport/lib/active_support/testing/assertions.rb', line 105 def assert_difference(expression, *args, &block) expressions = if expression.is_a?(Hash) = args[0] expression else difference = args[0] || 1 = args[1] Array(expression).index_with(difference) end exps = expressions.keys.map { |e| e.respond_to?(:call) ? e : lambda { eval(e, block.binding) } } before = exps.map(&:call) retval = _assert_nothing_raised_or_warn("assert_difference", &block) expressions.zip(exps, before) do |(code, diff), exp, before_value| actual = exp.call = -> do code_string = code.respond_to?(:call) ? _callable_to_source_string(code) : code error = "`#{code_string}` didn't change by #{diff}, but by #{actual - before_value}" error = "#{}.\n#{error}" if error end assert_equal(before_value + diff, actual, ) end retval end |
#assert_no_changes(expression, message = nil, from: UNTRACKED, &block) ⇒ Object
Assertion that the result of evaluating an expression is not changed before and after invoking the passed in block.
assert_no_changes 'Status.all_good?' do
post :create, params: { status: { ok: true } }
end
Provide the optional keyword argument :from
to specify the expected initial value. The comparison is done using case equality (===), which means you can specify patterns or classes:
# Exact value match
assert_no_changes -> { Status.all_good? }, from: true do
post :create, params: { status: { ok: true } }
end
# Case equality
assert_no_changes -> { user.token }, from: /\w{32}/ do
user.touch
end
# Type check
assert_no_changes -> { current_error }, from: RuntimeError do
retry_operation
end
An error message can be specified.
assert_no_changes -> { Status.all_good? }, 'Expected the status to be good' do
post :create, params: { status: { ok: false } }
end
280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 |
# File 'activesupport/lib/active_support/testing/assertions.rb', line 280 def assert_no_changes(expression, = nil, from: UNTRACKED, &block) exp = expression.respond_to?(:call) ? expression : -> { eval(expression.to_s, block.binding) } before = exp.call retval = _assert_nothing_raised_or_warn("assert_no_changes", &block) unless from == UNTRACKED = -> do error = "Expected initial value of #{from.inspect}, got #{before.inspect}" error = "#{}.\n#{error}" if error end assert from === before, end after = exp.call = -> do code_string = expression.respond_to?(:call) ? _callable_to_source_string(expression) : expression error = "`#{code_string}` changed" error = "#{}.\n#{error}" if error end if before.nil? assert_nil after, else assert_equal before, after, end retval end |
#assert_no_difference(expression, message = nil, &block) ⇒ Object
Assertion that the numeric result of evaluating an expression is not changed before and after invoking the passed in block.
assert_no_difference 'Article.count' do
post :create, params: { article: invalid_attributes }
end
A lambda can be passed in and evaluated.
assert_no_difference -> { Article.count } do
post :create, params: { article: invalid_attributes }
end
An error message can be specified.
assert_no_difference 'Article.count', 'An Article should not be created' do
post :create, params: { article: invalid_attributes }
end
An array of expressions can also be passed in and evaluated.
assert_no_difference [ 'Article.count', -> { Post.count } ] do
post :create, params: { article: invalid_attributes }
end
161 162 163 |
# File 'activesupport/lib/active_support/testing/assertions.rb', line 161 def assert_no_difference(expression, = nil, &block) assert_difference expression, 0, , &block end |
#assert_not(object, message = nil) ⇒ Object
Asserts that an expression is not truthy. Passes if object
is nil
or false
. “Truthy” means “considered true in a conditional” like if foo
.
assert_not nil # => true
assert_not false # => true
assert_not 'foo' # => Expected "foo" to be nil or false
An error message can be specified.
assert_not foo, 'foo should be false'
21 22 23 24 |
# File 'activesupport/lib/active_support/testing/assertions.rb', line 21 def assert_not(object, = nil) ||= -> { "Expected #{mu_pp(object)} to be nil or false" } assert !object, end |
#assert_nothing_raised ⇒ Object
Assertion that the block should not raise an exception.
Passes if evaluated code in the yielded block raises no exception.
assert_nothing_raised do
perform_service(param: 'no_exception')
end
48 49 50 51 52 |
# File 'activesupport/lib/active_support/testing/assertions.rb', line 48 def assert_nothing_raised yield.tap { assert(true) } rescue => error raise Minitest::UnexpectedError.new(error) end |
#assert_raises(*exp, match: nil, &block) ⇒ Object Also known as: assert_raise
Asserts that a block raises one of exp
. This is an enhancement of the standard Minitest assertion method with the ability to test error messages.
assert_raises(ArgumentError, match: /incorrect param/i) do
perform_service(param: 'exception')
end
34 35 36 37 38 |
# File 'activesupport/lib/active_support/testing/assertions.rb', line 34 def assert_raises(*exp, match: nil, &block) error = super(*exp, &block) assert_match(match, error.) if match error end |