我如何测试(rspec)需要太长时间的http请求?

时间:2012-01-25 18:50:59

标签: ruby rspec bdd

如果使用rspec请求时间过长,如何测试行为?

我正在考虑使用线程来模拟这个:

describe "Test" do 
  it "should timeout if the request takes too long" do 
    lambda {
      thread1 = Thread.new { #net::http request to google.com }
      thread2 = Thread.new { sleep(xx seconds) }
      thread1.join 
      thread2.join
    }.should raise_error
  end 
end

我想确保在首次发出请求之后,另一个线程“启动”,在这种情况下,它只是一个睡眠xx秒。然后我应该期望请求超时,因为执行

需要很长时间

我认为有更好的方法可以做到这一点。鉴于我请求的网址不相关。我只是想测试一下,如果执行时间太长,它确实会超时。

我可以使用stub(),expect()或任何rspec功能来模拟这个吗?

有没有办法可以将'block'传递给存根方法

http_request_to_google.stub(:connection).executethisblock(sleep for xx seconds)
.and_throw error ?

感谢任何帮助

3 个答案:

答案 0 :(得分:9)

如果请求未在20秒内完成,则以下测试失败。如果lambda中的代码没有引发Timeout :: Error。

,它也会失败

因此,成功的情况是long_running_stuff在不到20秒的时间内引发异常。

require 'timeout'

describe "Test" do 
  it "should timeout if the request takes too long" do 
    Timeout::timeout(20) do # 20 seconds
      lambda {
         long_running_stuff(:timeout => 10.seconds)
      }.should raise_error(Timeout::Error)
    end
  end 
end

答案 1 :(得分:6)

如果您纯粹关心Net :: HTTP引发Timeout :: Error,您可以随时强制它使用模拟返回错误,here是您可以使用RSpec的各种内容的良好汇编

这取决于您确切的Net :: HTTP请求,但Net::HTTP.should_receive(:request_get).and_raise(Timeout::Error)之类的内容会跳过任何网络调用,只会立即引发错误。

答案 2 :(得分:3)

我意识到这个问题很古老,但这是使用WebMock宝石的另一个解决方案:

stub_request(:any, 'www.google.com').to_timeout

使用Webmock存储请求的另一个好处是,即使您更换了HTTP客户端,这将继续工作,这会将您的测试与代码分离。