Reputation: 4047
This is my controller:
class PlansController
def use_new_card
@user = User.find_by_id(new_card_params[:user_id])
if new_stripe_card
...
end
private
def new_card_params
params.permit(:user_id, :stripeToken)
end
def new_stripe_card
StripeService.new({user_id: @user.id, customer_id: @user.stripe_customer_id, source: new_card_params[:stripeToken]}).new_card
end
end
I'm trying to write a controller spec that tests that when the proper parameters are POST
to the use_new_card
method, then new_stripe_card
's StripeService.new
gets these parameters appropriately.
My spec looks like this so far:
describe "when proper params are passed" do
before do
@user = User.create(...)
end
it "should allow StripeService.new to receive proper parameters" do
StripeService.should_receive(:new).with({user_id: @user.id, customer_id: @user.stripe_customer_id, source: "test"})
post :use_new_card, user_id: @user.id, stripeToken: "test"
end
end
But with that I'm getting
Failure/Error: post :use_new_card, user_id: @user.id, stripeToken: "test"
NoMethodError:
undefined method `new_card' for nil:NilClass
Totally fair, but I'm not sure how to fix this... I can't just stub new_card
because a stubbed method on a nil
object will still throw this error (I tried adding a StripeService.any_instance.stub(:new_card).and_return(true)
already into the before
block)
Upvotes: 1
Views: 744
Reputation: 47578
Stubbed methods return nil
by default. Use and_return
to specify the value returned by the stub::
StripeService.should_receive(:new).and_return(whatever)
or using the newer syntax
expect(StripeService).to receive(:new).and_return(whatever)
EDIT
Pardon my hand-waving. Your stub must return an object that will act like an instance of StripeService
to the extent required for the purposes of the test. So for example:
let(:new_card) { double }
let(:new_stripe_service) { double(new_card: new_card) }
...
expect(StripeService).to receive(:new).and_return(new_stripe_service)
Now when the test refers to new_stripe_service
, RSpec will return a test double that has a method stub named #new_card
, which itself is a double. You can add whatever additional stubs you need to make the test pass. Alternatively, you can return an actual instance of StripeService
for new_stripe_service
.
Upvotes: 1