gpt4 book ai didi

ruby - Rspec:访问 Klass.any_instance.stub block 内的实例

转载 作者:数据小太阳 更新时间:2023-10-29 07:18:49 27 4
gpt4 key购买 nike

Feature: test randomness
In order to make some code testable
As a developer
I want Array#sample to become Array#first

如果可以访问 Klass.any_instance.stub block 中的实例,那将是可能的。像这样:

Array.any_instance.stub(:sample) { instance.first }

但是那个 afaik 是不可能的。

无论如何,场景需要!

最佳答案

我找到了一个 hacky 解决方案,我已经在 rspec 版本 2.13.1 和 2.14.4 上对其进行了测试。您将需要 binding_of_caller gem。

Helper 方法 - 这应该可以由您的 rspec 示例调用:

# must be called inside stubbed implementation
def any_instance_receiver(search_limit = 20)
stack_file_str = 'lib/rspec/mocks/any_instance/recorder.rb:'
found_instance = nil
# binding_of_caller's notion of the stack is different from caller(), so we need to search
(1 .. search_limit).each do |cur_idx|
frame_self, stack_loc = binding.of_caller(cur_idx).eval('[self, caller(0)[0]]')
if stack_loc.include?(stack_file_str)
found_instance = frame_self
break
end
end
raise "instance not found" unless found_instance
return found_instance
end

那么在你的例子中:

Array.any_instance.stub(:sample) do
instance = any_instance_receiver
instance.first
end

我对堆栈搜索设置了限制,以避免搜索巨大的堆栈。我不明白您为什么需要增加它,因为它应该始终在 cur_idx == 8 左右。

请注意,在生产环境中可能不建议使用 binding_of_caller

关于ruby - Rspec:访问 Klass.any_instance.stub block 内的实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6194052/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com