Search code examples
ruby-on-railsrspecruby-on-rails-5

Testing model callback without firing email


I have a Rails 5 app and am testing a callback in my model. I want to be sure the callback is being called, but I do not want to actually fire the following line as it calls an API and sends an email:

response = bird.request(body, employee.location.birdeye)

My test is as follows:

it 'expects to send request through birdeye if valid' do
    req = build(:review_request)
    expect(req).to receive(:send_request)
    req.save
end

And this works, but the line mentioned above is fired. How can I test this callback without firing the call to bird.request()? Here's my model:

class ReviewRequest < ApplicationRecord
  belongs_to :user
  belongs_to :review, optional: true
  belongs_to :employee, optional: true

  after_create :send_request

  def client
    self.user.client
  end

  def send_request
    p "send_request callback..."
    ap self
    ap client
    body = {
        name: client.try(:name),
        emailId: user.email,
        phone: client.try(:phone),
        employees: [
            {
                emailId: employee.try(:email)
            }
        ]
    }

    bird = Birdeye.new
    response = bird.request(body, employee.location.birdeye)

    ap body
    return response
  end
end

Solution

  • If you only wants to check that the callback was called then I think mocking send_request might be the way to go. Try following

    
    before do
      allow_any_instance_of(ReviewRequest).to receive(:send_request).and_return(true)
    end
    
    it 'expects to call :send request after creating a ReviewRequest' do
        allow_any_instance_of(ReviewRequest).to receive(:send_request)
        create(:review_request)
    end
    

    If you want to test the implementation of send_request then stub Birdeye