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

时间:2022-12-27 19:16:10

How do I test the behavior if a request takes too long with rspec?

如果rspec请求时间太长,我该如何测试行为?

I am thinking of using thread to mock this:

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

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

I want to make sure that after the request is first made, another thread "kicks in" which in this case is just a sleep for xx seconds. Then I should expect the request to timeout because it takes too long to execute

我想确保在首次提出请求之后,另一个线程“开始”,在这种情况下,它只是一个休眠xx秒。然后我应该期望请求超时,因为执行时间太长

I think that there are better ways to do this. Given the fact that the url I am requesting is not relevant. I just want to test that it will indeed timeout if it takes too long to execute.

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

Can I use stub(), expect() or any rspec features to simulate this?

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

Is there any way that I can pass in a 'block' into stub method

有没有什么方法可以将'块'传递给存根方法

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

any help is appreciated

任何帮助表示赞赏

3 个解决方案

#1


4  

If you purely care about Net::HTTP raising a Timeout::Error, you could always just force it to return the error with a mock, here is a good compilation of various things you can use with RSpec.

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

It would depend on your exact Net::HTTP request, but something such as Net::HTTP.should_receive(:request_get).and_raise(Timeout::Error) would skip any networking calls and just raise the error immediately.

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

#2


8  

The below test fails if request doesn't finish in 20 seconds. It also fails if the code in the lambda doesn't raise Timeout::Error.

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

So, successful scenario is when long_running_stuff raises exception in less than 20 seconds.

因此,成功的情况是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

#3


2  

I realize this question is ancient, but here's another solution using the WebMock gem:

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

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

Another nice benefit to stubbing the request with Webmock is that this will continue to work even if you swap out your HTTP client, which decouples your tests from your code.

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

#1


4  

If you purely care about Net::HTTP raising a Timeout::Error, you could always just force it to return the error with a mock, here is a good compilation of various things you can use with RSpec.

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

It would depend on your exact Net::HTTP request, but something such as Net::HTTP.should_receive(:request_get).and_raise(Timeout::Error) would skip any networking calls and just raise the error immediately.

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

#2


8  

The below test fails if request doesn't finish in 20 seconds. It also fails if the code in the lambda doesn't raise Timeout::Error.

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

So, successful scenario is when long_running_stuff raises exception in less than 20 seconds.

因此,成功的情况是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

#3


2  

I realize this question is ancient, but here's another solution using the WebMock gem:

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

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

Another nice benefit to stubbing the request with Webmock is that this will continue to work even if you swap out your HTTP client, which decouples your tests from your code.

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