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