我希望能够说明,当open 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

但是在这种情况下,spec失败了,因为出现了一个nil.read错误。
这是我本周第二次遇到这个问题,上一次我试图用一个open()来模拟timeouterror,那次我放弃了,只是因为打开了这个类而导致了实际的超时。很明显,我可以通过尝试调用无效的url来引发socketerror,但我确信有一种正确的方法可以用rspec模拟这个问题。
更新:很明显,我没有很清楚地思考到,在深夜,错误实际上是当我在socketerror之后重新尝试url时,and raise(socketerror)部分工作正常。

最佳答案

根据您提供的信息,您所提供的这一行应该可以工作:我创建了一个很小的测试类和规范(见下文),其中只包含所描述的功能,并且一切都按预期进行。如果您可以提供更多的上下文,这可能会有帮助——例如,规范中完整的“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

07-27 13:58