RSpec и Open-URI как якобы вызвать поднятие SocketError / TimeoutError - PullRequest
5 голосов
/ 27 февраля 2009

Я хочу иметь возможность указать, что когда 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

Однако в этой ситуации спецификации не удается, как с ошибкой nil.read.

Это второй раз на этой неделе, когда я сталкивался с этой проблемой, в прошлый раз, когда я пытался смоделировать TimeoutError при переносе open() с timeout() {}, в этот раз я сдался и просто вызвал фактический тайм-аут случиться, открыв класс. Я мог бы , очевидно, заставить это вызвать SocketError, пытаясь вызвать недопустимый URL, но я уверен, что есть правильный способ сделать это с помощью RSpec.

Обновление: Я, очевидно, не думал ясно, что поздно ночью ошибка была на самом деле, когда я снова пробовал URL после SocketError, часть and_raise (SocketError) работала нормально.

1 Ответ

3 голосов
/ 27 февраля 2009

Строка, которую вы предоставили, должна работать на основе предоставленной вами информации: я создал крошечный тестовый класс и спецификацию (см. Ниже) только с описанной функциональностью, и все в порядке Было бы полезно, если бы вы могли предоставить немного больше контекста - например, полный блок «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
...