Rspec,你能存根一个 object 上不存在的方法吗(或者模拟一个可以采用任何方法的 object )?
Rspec, can you stub a method that doesn't exist on an object (or mock an object that can take any method)?
这听起来像是一个非常基础的问题...所以让我解释一下上下文。我正在从 Stripe 检索事件,但出于此目的,但这适用于我考虑过的其他事情。
我在 Stripe object 中需要的数据被埋没了,所以我不得不做 event.data.object.date.lines.first.id
。我不确定如何 mock/stub 这个...
我能想到的唯一方法是创建一个模拟 Stripe 事件的假模型 object(在我的这个例子中,请记住 Stripe 事件不能由用户创建)。然后我可以嘲笑那个假模型。但这真的是这样做的方法吗?有什么方法我可以只使用 Rspec 来存根整个 shebang 并说 event.data.object.date.lines.first.id
无论它出现在哪里都应该重新调整 1
?
哦还有...如果没有,事实证明我必须创建一个假模型...非常感谢提示,因为现在我认为这个 "Fake" 模型需要很多层children,完全不值得投入时间。
RSpec 没有提供特殊的机制来访问被测元素,所以是的,你需要以某种方式 stub
id
方法并让它 return 无论你希望(例如 1
)。
要做到这一点,您必须有一种方法来访问测试中的 event
对象,以便您可以存根它的 data
方法。一旦可以访问它,就可以使用 RSpec 的 receive_message_chain
匹配器来指定方法序列,如果调用这些方法,您将 return 1
.
如果有一些 public Strip
方法可以为事件模拟 return 一个 double
,那将是最直接的方法。
如果那不可能,您可以确定 event
的 class 并使用 allow_any_instance_of
方法存根它的 data
方法。生成的模拟如下,假设 Foo
是您关注的 event
对象的 class:
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
在 Stripe 的这种给定情况下,我会选择使用库进行模拟,而不是使用 RSpec 创建存根。我已经使用并强烈建议 stripe-ruby-mock.
这种方法的好处是您可以更接近地模拟 Stripe 的实际工作方式,并且您可以 switch to the actual stripe test api very easily。
这听起来像是一个非常基础的问题...所以让我解释一下上下文。我正在从 Stripe 检索事件,但出于此目的,但这适用于我考虑过的其他事情。
我在 Stripe object 中需要的数据被埋没了,所以我不得不做 event.data.object.date.lines.first.id
。我不确定如何 mock/stub 这个...
我能想到的唯一方法是创建一个模拟 Stripe 事件的假模型 object(在我的这个例子中,请记住 Stripe 事件不能由用户创建)。然后我可以嘲笑那个假模型。但这真的是这样做的方法吗?有什么方法我可以只使用 Rspec 来存根整个 shebang 并说 event.data.object.date.lines.first.id
无论它出现在哪里都应该重新调整 1
?
哦还有...如果没有,事实证明我必须创建一个假模型...非常感谢提示,因为现在我认为这个 "Fake" 模型需要很多层children,完全不值得投入时间。
RSpec 没有提供特殊的机制来访问被测元素,所以是的,你需要以某种方式 stub
id
方法并让它 return 无论你希望(例如 1
)。
要做到这一点,您必须有一种方法来访问测试中的 event
对象,以便您可以存根它的 data
方法。一旦可以访问它,就可以使用 RSpec 的 receive_message_chain
匹配器来指定方法序列,如果调用这些方法,您将 return 1
.
如果有一些 public Strip
方法可以为事件模拟 return 一个 double
,那将是最直接的方法。
如果那不可能,您可以确定 event
的 class 并使用 allow_any_instance_of
方法存根它的 data
方法。生成的模拟如下,假设 Foo
是您关注的 event
对象的 class:
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
在 Stripe 的这种给定情况下,我会选择使用库进行模拟,而不是使用 RSpec 创建存根。我已经使用并强烈建议 stripe-ruby-mock.
这种方法的好处是您可以更接近地模拟 Stripe 的实际工作方式,并且您可以 switch to the actual stripe test api very easily。