Rails 5.1 introduced assert_changes and assert_no_changes

Narendra Rajput

By Narendra Rajput

on May 9, 2017

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.

1
2@user = users(:john)
3assert_changes 'users(:john).status' do
4  post :update, params: {id: @user.id, user: {status: 'online'}}
5end
6

We can also pass a lambda as an expression.

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

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

1
2@light = Light.new
3assert_changes -> { @light.status }, from: 'off', to: 'on' do
4  @light.turn_on
5end
6

We can also specify test failure message.

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

assert_no_changes

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

Stay up to date with our blogs. Sign up for our newsletter.

We write about Ruby on Rails, ReactJS, React Native, remote work,open source, engineering & design.