Back to Blog

Rails 5.1 introduced assert_changes and assert_no_changes

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.


You might also like

If you liked this blog post, check out similar ones from BigBinary