gpt4 book ai didi

ruby - 在 sinatra 和 ruby​​ 中测试 Rack 超时

转载 作者:太空宇宙 更新时间:2023-11-03 16:31:40 24 4
gpt4 key购买 nike

我认为这很简单,但我在测试 rack-timeout gem 时遇到了问题。我有一个带有端点的 sinatra 基类,它执行一些逻辑。

module MyModule
class MySinatra < Sinatra::Base
use Rack::Timeout
Rack::Timeout.timeout = 10

get '/dosomething' do
#do the normal logic.
end
end
end

关于 rack-timeout gem 的更多信息是 here .我正在尝试设置一个测试,我可以在其中发送一个请求,我知道该请求将花费超过几秒钟的时间才能失败。

这是目前的测试

require "test/unit"
require "mocha/setup"
require 'rack/timeout'

def test_rack_timeout_should_throw_timed_out_exception_test
Rack::Timeout.stubs(:timeout).returns(0.0001)
assert_raises TimeoutError do
get "/dosomething"
end
Rack::Timeout.unstub
end

有很多方法可以做到这一点,但我不确定它们将如何实现

  1. 作为测试的一部分覆盖“/dosomething”方法以{sleep 3}
  2. 和上面一样做,但使用 stub 或模拟库
  3. 不要在测试中使用 get "/dosomething",而是创建一个 net::http 响应来保持请求打开。

对此有任何想法将不胜感激。

最佳答案

首先,您的测试实际上不会通过,因为错误没有传递给测试。它仅在服务器端引发。幸运的是,rack-test 提供了 last_response.errors 方法来检查是否有错误。因此我会按如下方式编写上述测试:

def test_rack_timeout_should_throw_timed_out_exception
Rack::Timeout.stubs(:timeout).returns(0.0001)

get '/dosomething'

assert last_response.server_error?, 'There was no server error'
assert last_response.errors.include?('Timeout::Error'), 'No Timeout::Error raised'

Rack::Timeout.unstub
end

现在唯一要做的就是通过覆盖路由来模拟缓慢的响应。起初看起来很简单,但后来我意识到它根本不是那么简单。我摆弄了很多东西并在这里想出了这个:

class Sinatra::Base
def self.with_fake_route method, route, body
old_routes = routes.dup
routes.clear
self.send(method.to_sym, route.to_s, &body.to_proc)
yield
routes.merge! old_routes
end
end

它将允许您在传递给该方法的 block 内暂时仅使用一条路线。例如,现在您可以通过以下方式模拟缓慢的响应:

MyModule::MySinatra.with_fake_route(:get, '/dosomething', ->{ sleep 0.0002 }) do
get '/dosomething'
end

请注意, block 内的get '/dosomething' 不是临时路由的定义,而是一种 Rack 测试触发模拟请求的方法。实际覆盖路由以 with_route 的参数形式指定。

这是我能想到的最佳解决方案,但我希望看到更优雅的方法来解决这个问题。

完整的工作示例(在 Ruby 1.9.3.p385 上运行):

require 'sinatra/base'
require 'rack/timeout'

module MyModule
class MySinatra < Sinatra::Base
use Rack::Timeout
Rack::Timeout.timeout = 10

get '/dosomething' do
'foo'
end
end
end




require 'test/unit'
require 'rack/test'
require 'mocha/setup'

class Sinatra::Base
def self.with_fake_route method, route, body
old_routes = routes.dup
routes.clear
self.send(method.to_sym, route, &body)
yield
routes.merge! old_routes
end
end

class Tests < Test::Unit::TestCase
include Rack::Test::Methods

def app
MyModule::MySinatra
end

def test_rack_timeout_should_throw_timed_out_exception
Rack::Timeout.stubs(:timeout).returns(0.0001)

MyModule::MySinatra.with_fake_route(:get, '/dosomething', ->{ sleep 0.0002 }) do
get '/dosomething'
end

assert last_response.server_error?, 'There was no server error'
assert last_response.errors.include?('Timeout::Error'), 'No Timeout::Error raised'

Rack::Timeout.unstub
end
end

产生:

1 tests, 2 assertions, 0 failures, 0 errors, 0 skips

关于ruby - 在 sinatra 和 ruby​​ 中测试 Rack 超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14851952/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com