RSpec和Open-URI如何模拟引发SocketError / TimeoutError

时间:2009-02-26 23:09:02

标签: ruby rspec raise open-uri

我希望能够符合规范的是,当打开-URI open()调用或者超时或抛出一个异常如SocketError我处理事情的预期,但我有这个麻烦。

这是我的规范(对于SocketError):

@obj.should_receive(:open).with("some_url").and_raise(SocketError)

我正在使用open-uri的对象部分:

begin
  resp = open(url)
  resp = resp.read
rescue SocketError
  something = true
end

但是在这种情况下,规范会因nil.read错误而失败。

这是这个星期我已经遇到这个问题的第二次,上一次我试图包装时,模拟TimeoutError open()具有timeout() {},那个时候我放弃了,只是通过打开课程导致实际超时。我可能显然导致这个通过尝试调用无效的URL来抛出SocketError,但我确信有一种正确的方法可以用RSpec模拟它。

更新:我显然并没有考虑清楚,在深夜,错误实际上是当我重新尝试了SocketError后的URL,该and_raise(SocketError)部分工作得很好

1 个答案:

答案 0 :(得分:3)

根据您提供的信息,您提供的行应该有效:我只使用所描述的功能制作了一个小型测试类和规范(见下文),并且事情按预期运行。如果您可以提供更多的上下文可能会有所帮助 - 例如,规范中的完整“it”块可能会暴露其他一些问题。

如上所述,以下规范通过,我相信它会捕获您尝试验证的逻辑:

require 'rubygems'
require 'spec'

class Foo
  attr_accessor :socket_error

  def get(url)
    @socket_error = false
    begin
      resp = open(url)
      resp = resp.read
    rescue SocketError
      @socket_error = true
    end
  end
end

describe Foo do
  before do
    @foo = Foo.new
  end

  it "should handle socket errors" do
    @foo.should_receive(:open).with("http://www.google.com").and_raise(SocketError)
    @foo.get("http://www.google.com")
    @foo.socket_error.should be_true
  end
end