gpt4 book ai didi

ruby - 如何在 Mocha 中 stub 具有特定参数的方法(并保留其他参数未 stub 的调用)?

转载 作者:行者123 更新时间:2023-12-04 12:01:32 30 4
gpt4 key购买 nike

这个问题可能看起来像 this one 的重复但接受的答案对我的问题没有帮助。

语境

由于 Rails 5 不再支持在 Controller 测试中直接操作 session (现在继承自 ActionDispatch::IntegrationTest),我将走上模拟和 stub 的黑暗道路。

我知道这是不好的做法,有更好的方法来测试 Controller (我确实理解他们转向集成测试)但我不想运行完整的集成测试并在单个测试中调用多个操作只是为了设置一个特定的 session 变量。

场景

使用 Mocha 模拟/ stub session 变量实际上很容易:

ActionDispatch::Request::Session.any_instance.stubs(:[]).with(:some_variable).returns("some value")

问题是,Rails 在 session 中存储了很多东西(只需在您的一个 View 中的任何位置执行 session.inspect)并 stub :[]方法显然会阻止访问其中任何一个(因此 session[:some_other_variable] 在测试中将不再有效)。

问题

有没有办法 stub /模拟 :[]仅在使用特定参数调用时才调用方法,并且不保留所有其他调用?

我本来希望像
ActionDispatch::Request::Session.any_instance.stubs(:[]).with(:some_variable).returns("some value")
ActionDispatch::Request::Session.any_instance.stubs(:[]).with(anything).returns(original_value)

但我找不到完成它的方法。

最佳答案

据我所知,这是 mocha 中没有的功能
https://github.com/freerange/mocha/issues/334
我知道这确实存在于 rspec-mock https://github.com/rspec/rspec-mocks/blob/97c972be57f2c060a4a7fb8a3c5700a5ede693f0/spec/rspec/mocks/stub_implementation_spec.rb#L29
但是,您可以这样做的一种hacky 方法是将原始 session 存储在一个对象中,然后模拟每当 Controller 接收 session 时,它返回另一个模拟对象,在这种情况下,您可以返回模拟的 velue,或委托(delegate)调用到原始 session

class MySession
def initialize(original)
@original = original
end
def [](key)
if key == :mocked_key
2
else
original[key]
end
end
end

let!(original_session) { controller.send(:session) }
let(:my_session) { MySession.new(original_session) }

before do
controller.stubs(:session) { my_session }
end
猜猜 mocha 也允许你做块模拟,所以你不需要这个类,但你需要那个 original_session被称为
但我没有看到干净的方式

关于ruby - 如何在 Mocha 中 stub 具有特定参数的方法(并保留其他参数未 stub 的调用)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43112538/

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