0

私の質問は、次の 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
4

1 に答える 1

0

スペック内のオブジェクトに期待値を設定しています(@stripe_msub)。ただし、コントローラーでは、おそらくデータベースから教師@stripe_subscriptionをロードし、そのサブスクリプションを取得します( )。

データベースを介したラウンドトリップのため、このオブジェクトは期待値を設定したオブジェクトと同じではありません。したがって、(仕様で)期待値を設定したオブジェクトは@stripe_msubメソッド呼び出しを受信せず、rspecは文句を言います。

これを修正するには、すべてのデータベース呼び出しをスタブし、仕様のオブジェクトがコントローラーに表示されることを確認する必要があります。コントローラーのどこに正確に設定されているかわからないので@teacher(フィルターの1つにあると思います)、正確な解決策を提供することはできませんが、次のようになります。

# 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)
于 2012-10-10T08:03:21.933 に答える