ruby-on-rails - RSpec - stub 模块中的#super调用#prepend monkeypatch

标签 ruby-on-rails ruby rspec ruby-on-rails-5

我正在将使用 alias_method_chain 的 monkeypatches 转换为 Module#prepend。 (主要是因为 active_support v5.0 弃用了 alias_method_chain。)但这样做会使 rspec 测试更加困难。

我的旧 alias_method_chain 代码如下所示:

class Client
  def call_with_reconnect
    begin
      call_without_reconnect
    rescue => ex
      reconnect
      call_without_reconnect
    end
  end
  alias_method_chain :call, :reconnect
end

我可以用 rspec 来测试这个:

it "should silently reconnect when the original request expires" do
  allow(subject).to receive(:call_without_reconnect).and_raise(TimeoutError)
  expect{ subject.call }.to_not raise_error(TimeoutError)
end

我的新 Module#prepend 代码如下:

class Client
  module MethodOverrides
    def call
      begin
        super
      rescue => ex
        reconnect
        super
      end
    end
  end
  prepend MethodOverrides
end

此代码有效,但我不知道如何测试它。我想在调用旧方法时强制出现超时错误,但我无法对 super 调用进行 stub 。而且我无法将调用 stub 到 call,因为这也是我的 monkeypatch 方法的名称。

最佳答案

只是玩弄你的代码,我在覆盖之后重写了 Client 上的 call 方法,它覆盖了原来的 Client#call应该有助于对引发 TimeoutError 的方法进行 stub 。

给定:

class Client
  def call
    puts "super"
  end

  module MethodOverrides
    def call
      begin
        puts "override"
        super
      rescue => ex
        puts "reconnect"
        super
      end
    end
  end
  prepend MethodOverrides
end

我跑了:

Client.new.call
# override
# super
# => nil

然后我手动猴子修补了 Client#call 方法:

class Client
  def call
    raise "a timeout happened"
  end
end

我得到了:

Client.new.call
# override
# reconnect
# => RuntimeError: a timeout happened

这与您之前所拥有的不完全相同,但是通过对您的规范进行一些重构,您可以使用这种方法,即导致超时并查看是否调用了 reconnect 方法。或者更好的是,Client#call 在有和没有超时的情况下被调用时都有预期的副作用。换句话说,测试类的正确行为。

关于ruby-on-rails - RSpec - stub 模块中的#super调用#prepend monkeypatch,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39477111/

相关文章:

ruby-on-rails - openid.ui.mode 使用 rails 的 openid_authentication 插件

ruby-on-rails-3 - Rails 3 - 通过 rspec 正确测试 PUT 方法

ruby-on-rails - 使用 zeus : Postgres is being accessed by other users 进行 cucumber 和 RSpec 测试

ruby-on-rails - 在 RSpec Controller 规范中测试 RJS 的最佳方法?

ruby-on-rails - 将 Rails 插件安装为 git 子模块

sql - rails Postgres : Query to find corresponding models in a "triangle of models"

ruby - Ruby 是否提供响应 OS X 上的 Apple 事件的机制?

ruby-on-rails - 使用rails中的 session 变量在模型中评分算法

Ruby 哈希排列

ruby-on-rails-3 - rspec Controller 空 session