0

I have a model that has a before_save callback. In that, I want to call a API to calculate something and save it. When the API is unavailable and throws an error, it then should just save 'not available' (which is totally fine, it's just a small project I do for myself). It should look like this:

class User < ApplicationRecord
  before_save :calc

  private

  def calc
    self.calculated_something = API_call
    rescue StandardError
      self.calculated_something = 'not available'
  end
end

I know how to test the calculated_something case (with VCR), but how do I mock the failing API call? I don't want to use an empty VCR cassette btw. Is this even the correct way to save the calculated_something?

I hope my question is clear, thanks.

sam
  • 191
  • 1
  • 8
  • 1
    You can mock the `user.calc` method by doing the below in your test `before do allow(user).to receive(:calc).and_return true end` – Moiz Mansur Apr 13 '22 at 06:35
  • @MoizMansur and how would I check that it saved 'not available'? or is that also done by your code? – sam Apr 13 '22 at 07:16
  • Oh im sorry i misunderstood the question. In that case your 2 cases would be when API_call fails and API_call passes. See https://stackoverflow.com/a/32354467/5671433 – Moiz Mansur Apr 13 '22 at 09:20
  • " Is this even the correct way to save the calculated_something?". Thats a matter of opinion but I would say no. Using a callback both makes your model aware of the external API and relies on implicit instead of explicit logic. This adds even more responsibity to a class that already does way to many things. – max Apr 13 '22 at 11:43
  • I would use a service object instead to handle creating the object with input from the API. That gives you much better options to control when and where this happens and to handle both API errors and errors related to actually saving the record. `rescue StandardError` is also an anti-pattern known as [Pokémon exception handling](https://wiki.c2.com/?PokemonExceptionHandling) which will make debugging very difficult and can leave the system in an unstable state. You should only rescue specific errors that you actually know how to deal with. – max Apr 13 '22 at 11:47

0 Answers0