method

assert_changes

assert_changes(expression, message = nil, from: UNTRACKED, to: UNTRACKED, &block)
public

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