这可能听起来像一个非常基本的问题......所以让我解释一下背景。我正在从Stripe中检索一个事件,但就此而言,这适用于我考虑过的其他事情。
我在Stripe对象中需要的数据是埋藏的,所以我必须做event.data.object.date.lines.first.id
。我不确定如何模拟/存根...
我能想到的唯一方法就是创建一个模拟Stripe事件对象的假模型(在本例中对我来说,请记住Stripe事件不能由用户创建)。然后我可以模仿那个假模型。但这真的是这样做的吗?是否有某种方法我可以使用Rspec来存储整个shebang并说event.data.object.date.lines.first.id
只要它出现在哪里就应该重新调用1
?
哦,还有...如果没有,事实证明我必须创建一个假模型...提示非常感谢,因为现在我认为这个“假”模型需要多层儿童,并且完全不值得花时间投资。
答案 0 :(得分:1)
在Stripe的这种情况下,我选择使用库进行模拟,而不是使用RSpec创建存根。我已经使用并强烈建议stripe-ruby-mock。
这种方法的好处是,您可以更密切地嘲笑Stripe的实际工作方式,并且switch to the actual stripe test api very easily可以。
答案 1 :(得分:0)
RSpec没有提供访问被测元素的特殊机制,所以是的,您需要以某种方式stub
id
方法并让它返回您想要的任何内容(例如1
)。
为此,您必须有办法访问测试中的event
对象,以便您可以使用data
方法存根。一旦你可以访问它,你就可以使用RSpec的receive_message_chain
匹配器来指定方法的顺序,如果被调用,你将返回1
。
如果有一些公共Strip
方法,您可以模拟为事件返回double
,这将是最简单的方法。
如果无法做到这一点,您可以确定event
的类,并使用allow_any_instance_of
方法来存根data
方法。结果模拟如下,假设Foo
是您关注的event
对象的类:
allow_any_instance_of(Foo)).to receive_message_chain(
:data, :object, :date, :lines, :first, :id).and_return(1)
这是一个通过的测试:
module Stripe
class Event ; end
end
describe 'stack overflox example' do
it 'should pass' do
event = Stripe::Event.new
expect(event).to receive_message_chain(:data, :object, :date, :lines, :first, :id).and_return(23)
expect(event.data.object.date.lines.first.id).to eq(23)
end
end