RSpec - 存储#super调用模块#prepend monkeypatch

时间:2016-09-13 18:53:59

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

我正在使用alias_method_chain转换为Module#prepend的monkeypatches。 (主要是因为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调用。我无法将调用存根到call,因为这也是我的monkeypatch方法的名称。

1 个答案:

答案 0 :(得分:0)

只是玩弄你的代码,我在覆盖之后在call上重写了Client方法,它覆盖了原来的Client#call,这有助于简化方法来提升TimeoutError 1}}。

假设:

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在使用和不使用超时调用时具有预期的副作用。换句话说,测试类的正确行为。