【问题标题】:Mocking Stripe::Charge - RSpec says that it does not implement :retrieveMocking Stripe::Charge - RSpec 说它没有实现 :retrieve
【发布时间】:2015-09-20 00:33:11
【问题描述】:
我试图在我的一些测试中模拟 Stripe::Charge.retrieve,但我得到了错误:
Failure/Error: allow_any_instance_of(Stripe::Charge).to receive(:retrieve)
Stripe::Charge does not implement #retrieve
我猜测 Stripe API 会进行某种反射来生成此方法。有没有办法模拟这种方法?或者可能是一种关闭 RSpec 功能的方法,该功能验证是否存在用于特定测试的模拟方法?
【问题讨论】:
标签:
ruby-on-rails
ruby
unit-testing
rspec
【解决方案1】:
Stripe::Charge.retrieve 是一个类方法,但您试图像实例方法一样模拟它。这里最大的提示是该方法称为“retrieve”-您正在尝试获取 Stripe::Charge 对象,并且在 Ruby 中使用类方法更为惯用。 Rspec 的错误不是很有用;如果它说“Stripe::Charge 的实例不实现#retrieve”会更准确。
好消息是你可以在 Rspec 中非常直接地模拟它:
allow(Stripe::Charge).to receive(:retrieve)
这里有一个简短的示例来演示这一点,取自包含 Stripe gem 和 rspec-rails 的 Rails 项目。首先,一个大部分为空的支付模式:
class Payment < ActiveRecord::Base
def get_stripe_charge(payment_ref)
Stripe::Charge.retrieve(payment_ref)
end
end
现在是 spec/models/payment_spec.rb 来演示模拟:
require 'rails_helper'
RSpec.describe Payment, type: :model do
it "Allows retrieval of a payment" do
allow(Stripe::Charge).to receive(:retrieve).and_return("Avocados") # A mock object would be more useful here.
payment = Payment.new
expect(payment.get_stripe_charge("whatever")).to eql("Avocados")
end
end