【问题标题】:How to stub method with specific parameter (and leave calls with other parameters unstubbed) in Mocha?如何在 Mocha 中对具有特定参数的方法进行存根(并保留其他参数未存根的调用)?
【发布时间】:2017-03-30 08:35:27
【问题描述】:

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

上下文

由于 Rails 5 不再支持在控制器测试中直接操作会话(现在从 ActionDispatch::IntegrationTest 继承),我将走上模拟和存根的黑暗道路。

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

场景

使用Mocha 模拟/存根会话变量实际上非常容易:

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

问题是,Rails 在会话中存储了 很多 内容(只需在您的一个视图中的任何位置执行 session.inspect)并且存根 :[] 方法显然会阻止对其中任何一个的访问(所以测试中的session[:some_other_variable] 将不再起作用)。

问题

有没有办法只在使用特定参数调用 :[] 方法时存根/模拟,而让所有其他调用不被存根?

我本来希望得到类似的东西

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

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

【问题讨论】:

  • 尝试stub(:[]) 而不是stubs(:[])
  • 我基于对 Mocha 内部结构的深入研究,对原始问题提出了一些想法。希望它可以帮助某人。不在这里发布我的解决方案,因为它不是那么好,但总比没有好;)

标签: ruby ruby-on-rails-5 ruby-mocha


【解决方案1】:

据我所知,这是 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 方法是将原始会话存储在一个对象中,然后模拟每当控制器接收到会话时,它会返回另一个模拟对象,在这种情况下你可以返回一个模拟的 velue,或者将调用委托给原始会话

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

但我没有看到干净的方法

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-06
    • 1970-01-01
    • 2016-03-03
    • 1970-01-01
    相关资源
    最近更新 更多