Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rspec: How to test a method that raises an error

I have a SubscriptionHandler class with a call method that creates a pending subscription, attempts to bill the user and then error out if the billing fails. The pending subscription is created regardless of whether or not the billing fails

class SubscriptionHandler

  def initialize(customer, stripe_token)
    @customer = customer
    @stripe_token = stripe_token
  end

  def call
    create_pending_subscription
    attempt_charge!
    upgrade_subscription
  end

  private

  attr_reader :stripe_token, :customer

  def create_pending_subscription
   @subscription = Subscription.create(pending: true, customer_id: customer.id)
  end

  def attempt_charge!
    StripeCharger.new(stripe_token).charge!  #raises FailedPaymentError
  end

  def upgrade_subscription
   @subscription.update(pending: true)
  end

 end

Here is what my specs look like:

describe SubscriptionHandler do

  describe "#call" do
    it "creates a pending subscription" do
      customer = create(:customer)
      token = "token-xxx"
      charger = StripeCharger.new(token)
      allow(StripeCharger).to receive(:new).and_return(charger)
      allow(charger).to receive(:charge!).and_raise(FailedPaymentError)
      handler = SubscriptionHandler.new(customer, token)

      expect { handler.call }.to change { Subscription.count }.by(1) # Fails with FailedPaymentError
    end
  end
end

But this does not change the subscription count, it fails with the FailedPaymentError. Is there a way to check that the subscription count increases without the spec blowing up with FailedPaymentError.

like image 369
nathanfredrick Avatar asked Sep 05 '25 02:09

nathanfredrick


1 Answers

You should be able to use Rspec compound expectations for this

https://relishapp.com/rspec/rspec-expectations/docs/compound-expectations

So I'll re-write your expectation to something like this:

expect { handler.call }.
 to raise_error(FailedPaymentError).
 and change { Subscription.count }.by(1)
like image 110
Adim Avatar answered Sep 07 '25 23:09

Adim