Search code examples
ruby-on-railsrubyrspecrspec-rails

testing callbacks after_update rspec


I have 2 models User.rb and Client.rb. Relationship is:

User.rb

has_and_belongs_to_many :clients, inverse_of: :users

Client

has_and_belongs_to_many :users, inverse_of: :clients

Callbacks in User.rb model

after_create :client_not_erasable
after_update :assign_client


def client_not_erasable
.
.
end

def assign_client
  def to_param
    return Client.find(client_to_add) unless client_to_add.nil?
  end
  unless client_to_add.nil?
    if to_param.users.count.zero? && client_to_add.present?
      to_param.update_attributes(erasable:false)
    end
  end
end

First callback after_create :client_not_erasable is working fine, but second callback after_update :assign_client doesn't work. I'm getting true. I should get false

Hooks

describe 'after_save and after_update callbacks' do
  let(:user) { build(:user) }
  let(:client) { build(:client) }
  it 'erasable client field should be false after of an user create' do
    user.clients.count == 1
    user.clients[0].erasable = true
    user.run_callbacks :create
    expect(user.clients[0].erasable).to be(false)
  end
  it 'erasable client field should be false after of it is assigned to user' do
    client.erasable = true
    user.run_callbacks :update
    expect(client.erasable).to be(false)
  end
end

Testing result:

Failures:

  1) User Validations after_save and after_update erasable client field should be false after of it is assigned to user
     Failure/Error: expect(client.erasable).to be(false)

       expected false
            got true
     # ./spec/models/user_spec.rb:93:in `block (4 levels) in <top (required)>'

thank you!


Solution

  • Thank you to yzalavin response. the code that is finally working fine is:

    Hooks

    context 'Hooks' do
      let(:client) { build(:client) }
      let(:user) { build(:user) }
      let!(:users) { create_list(:user, 2, clients: [client]) } 
      it 'erasable client field should be false after of an user create' do
        user.clients.count == 1
        user.clients[0].erasable = true
        user.run_callbacks :create
        expect(user.clients[0].erasable).to be(false)
      end
      it 'erasable client field should be false after of it is assigned to user' do
        client.erasable = true
        user.run_callbacks :update
        expect(client.reload.erasable).to be(false)
      end
    end
    

    Thank you