Rspec 测试 public 控制器方法将参数传递给私有控制器方法

Rspec test public controller method passing params to private controller method

这是我的控制器:

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

我正在尝试编写一个控制器规范来测试当 POSTuse_new_card 方法的正确参数时,new_stripe_cardStripeService.new 得到这些参数适当。

到目前为止,我的规范如下所示:

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

但是我得到

Failure/Error: post :use_new_card, user_id: @user.id, stripeToken: "test"
 NoMethodError:
   undefined method `new_card' for nil:NilClass

完全公平,但我不确定如何解决这个问题...我不能只存根 new_card 因为 nil 对象上的存根方法仍然会抛出此错误(我尝试将 StripeService.any_instance.stub(:new_card).and_return(true) 添加到 before 块中)

存根方法 return 默认情况下 nil。使用 and_return 指定由存根::

编辑的值 return
StripeService.should_receive(:new).and_return(whatever)

或使用更新的语法

expect(StripeService).to receive(:new).and_return(whatever)

编辑

请原谅我的挥手。您的存根必须 return 一个对象,该对象将在测试目的所需的范围内充当 StripeService 的实例。例如:

let(:new_card) { double }
let(:new_stripe_service) { double(new_card: new_card) }
...
expect(StripeService).to receive(:new).and_return(new_stripe_service)

现在,当测试引用 new_stripe_service 时,RSpec 将 return 一个测试替身,它有一个名为 #new_card 的方法存根,它本身就是一个替身。您可以添加使测试通过所需的任何其他存根。或者,您可以 return StripeService 的实际实例用于 new_stripe_service.