我的问题是,为什么我收到以下rspec错误消息? (下面的代码)我在StripeSubscription模型上创建了:update_payment方法。我已经在这里待了几个小时而且很困惑。
Failure/Error: @stripe_msub.should_receive(:update_payment).and_return(@stripe_msub)
(#<StripeSubscription:0xb879154>).update_payment(any args)
expected: 1 time
received: 0 times
###Rspec test###
describe "PUT 'update'" do
context "signed-in teacher" do
before(:each) do
@teacher = Factory(:teacher)
@teacher_upload = Factory(:teacher_upload,:teacher_id=>@teacher.id)
@stripe_mplan = Factory(:stripe_plan)
@new_stripe_card_token = 528
@stripe_msub = Factory(:stripe_subscription,:teacher_id=>@teacher.id,:stripe_plan_id=>@stripe_mplan.id, :email=>@teacher.email,:account_status=>Acemt::Application::STRIPE_SUBSCRIPTION_ACCOUNT_STATUS[:active])
@stripe_msub.stub!(:update_payment).and_return(@stripe_msub)
StripeSubscription.stub!(:update_payment).and_return(@stripe_msub)
StripeSubscription.stub!(:update_attributes).and_return(true)
@stripe_customer = mock('Stripe::Customer')
Stripe::Customer.stub!(:retrieve).with(@stripe_msub.stripe_customer_token).and_return(@stripe_customer)
@stripe_customer.stub(:card=).and_return(true)
@stripe_customer.stub(:save).and_return(true)
test_sign_in(@teacher)
end
it "should update credit card information" do
@stripe_msub.should_receive(:update_payment)
Stripe::Customer.should_receive(:retrieve).with(@stripe_msub.stripe_customer_token).and_return(@stripe_customer)
@stripe_customer.should_receive(:card=)
@stripe_customer.should_receive(:save).and_return(@stripe_customer)
put :update, :teacher_id=>@teacher.id, :stripe_subscription=>{:stripe_plan_id=>@stripe_msub.stripe_plan_id, :teacher_id=>@stripe_msub.teacher_id, :email=>@stripe_msub.email, :stripe_customer_token=>@stripe_msub.stripe_customer_token,:stripe_card_token=>@new_stripe_card_token,:account_status=>@stripe_msub.account_status}
@teacher.stripe_subscription.should == @stripe_msub
response.should redirect_to teacher_path(@teacher)
end
end #signed in teacher
end #PUT update
###controller###
class StripeSubscriptionsController < ApplicationController
before_filter :signed_in_teacher
before_filter :correct_teacher
:
def update
#@stripe_subscription = StripeSubscription.find_by_id(params[:id])
@stripe_subscription = @teacher.stripe_subscription
if @stripe_subscription.update_payment(params[:stripe_subscription])
#handle successful update
flash[:success] = "Credit card updated"
sign_in @teacher
redirect_to @teacher
else
render 'edit'
end
end
:
end
###model###
class StripeSubscription < ActiveRecord::Base
#attr_accessible :email, :plan_id, :stripe_customer_token, :teacher_id, :account_status
validates_presence_of :stripe_plan_id
validates_presence_of :email
validates_presence_of :teacher_id
belongs_to :stripe_plan, :class_name=>"StripePlan"
belongs_to :teacher
attr_accessor :stripe_card_token
def save_with_payment
if valid?
customer = Stripe::Customer.create(description: email, plan: stripe_plan_id, card: stripe_card_token)
self.stripe_customer_token = customer.id
save!
end
rescue Stripe::InvalidRequestError => e
logger.error "Stripe error while creating customer: #{e.message}"
errors.add :base, "There was a problem with your credit card."
end
def update_payment(stripe_params)
if valid?
customer = Stripe::Customer.retrieve(self.stripe_customer_token)
customer.card = stripe_params[:stripe_card_token]
status = customer.save #update card info on Stripe
update_attributes(stripe_params) #save StripeSubscription object
end
rescue Stripe::InvalidRequestError => e
logger.error "Stripe error while updating your credit card: #{e.message}"
errors.add :base, "There was a problem with your credit card."
end
end
答案 0 :(得分:0)
您正在为规范(@stripe_msub
)中的对象设置期望值。但是,在控制器中,您可能从数据库加载教师并获得其订阅(@stripe_subscription
)。
由于通过数据库的往返,此对象与您设置的期望对象不同,因此您设置预期的对象(规范中的@stripe_msub
)从未接收到方法调用因此rspec抱怨。
要解决此问题,您必须将所有数据库调用存根,并确保您的规范中的对象出现在控制器中。我不知道控制器中确切地设置了@teacher
(我想在其中一个过滤器中)所以我不能给你确切的解决方案,但它会是这样的:
# I assume this is the implentation of your filter in the controller
def signed_in_teacher
@teacher = Teacher.find_by_id(params[:teacher_id])
end
# Then you would have to add the following mocks/stubs to your spec
Teacher.should_receive(:find_by_id).once.with(@teacher.id).and_return(@teacher)