← Blog

Rails 5.1 introduced assert_changes and assert_no_changes

This blog is part of our Rails 5.1 series.

Rails 5.1 has introduced assert_changes and assert_no_changes. It can be seen as a more generic version of assert_difference and assert_no_difference.

assert_changes

assert_changes asserts the value of an expression is changed before and after invoking the block. The specified expression can be string like assert_difference.


@user = users(:john)
assert_changes 'users(:john).status' do
  post :update, params: {id: @user.id, user: {status: 'online'}}
end

We can also pass a lambda as an expression.


@user = users(:john)
assert_changes -> {users(:john).status} do
  post :update, params: {id: @user.id, user: {status: 'online'}}
end

assert_changes also allows options :from and :to to specify initial and final state of expression.


@light = Light.new
assert_changes -> { @light.status }, from: 'off', to: 'on' do
  @light.turn_on
end

We can also specify test failure message.


@invoice = invoices(:bb_client)
assert_changes -> { @invoice.status }, to: 'paid', 'Expected the invoice to be marked paid' do
  @invoice.make_payment
end

assert_no_changes

assert_no_changes has same options and asserts that the expression doesn't change before and after invoking the block.

Narendra Rajput avatar
Written byNarendra Rajput
Newsletter

Stay up to date with our blogs.

Subscribe to receive an email notification for a new blog post.