【问题标题】:Mock a HTTP request that times out with HTTPretty使用 HTTPretty 模拟超时的 HTTP 请求
【发布时间】:2015-02-25 17:12:27
【问题描述】:

使用 Python 的 HTTPretty library,我可以创建选择的模拟 HTTP 响应,然后选择它们,即使用 requests library,如下所示:

import httpretty
import requests

# set up a mock
httpretty.enable()
httpretty.register_uri(
            method=httpretty.GET,
            uri='http://www.fakeurl.com',
            status=200,
            body='My Response Body'
        )

response = requests.get('http://www.fakeurl.com')

# clean up
httpretty.disable()
httpretty.reset()

print(response)

输出:<Response [200]>

是否还有可能注册一个无法访问的 uri(例如连接超时、连接被拒绝……),这样根本就没有收到任何响应(这与已建立的连接不同,它给出了一个HTTP 错误代码如 404)?

我想在单元测试中使用此行为,以确保我的错误处理按预期工作(在“未建立连接”和“建立连接,错误的 HTTP 状态代码”的情况下会做不同的事情)。作为一种解决方法,我可以尝试连接到无效的服务器,例如http://192.0.2.0,无论如何都会超时。但是,我更愿意在不使用任何真实网络连接的情况下进行所有单元测试。

【问题讨论】:

    标签: python unit-testing python-requests httpretty


    【解决方案1】:

    同时我明白了,使用HTTPretty callback body 似乎会产生所需的行为。请参阅下面的内联 cmets。 这实际上与我正在寻找的不完全相同(它不是 无法访问的服务器,因此请求超时 而是 抛出的服务器一旦达到超时异常,但是对于我的用例来说效果是一样的。

    不过,如果有人知道不同的解决方案,我很期待。

    import httpretty
    import requests
    
    # enable HTTPretty
    httpretty.enable()
    
    # create a callback body that raises an exception when opened
    def exceptionCallback(request, uri, headers):
    
        # raise your favourite exception here, e.g. requests.ConnectionError or requests.Timeout
        raise requests.Timeout('Connection timed out.')
    
    # set up a mock and use the callback function as response's body
    httpretty.register_uri(
                method=httpretty.GET,
                uri='http://www.fakeurl.com',
                status=200,
                body=exceptionCallback
            )
    
    # try to get a response from the mock server and catch the exception
    try:
        response = requests.get('http://www.fakeurl.com')
    except requests.Timeout as e:
    
        print('requests.Timeout exception got caught...')
        print(e)
    
        # do whatever...
    
    # clean up
    httpretty.disable()
    httpretty.reset()
    

    【讨论】:

    • 正如您所注意到的,这并没有真正测试运行时行为,因为 requests.get 没有给定 timeout 参数 hangs indefinitely 即使这些年后在 requests 2.25.1 中。这可以测试代码在超时时会做什么,但根本不会测试它是否会超时。
    猜你喜欢
    • 2014-08-14
    • 2014-10-19
    • 2012-12-11
    • 1970-01-01
    • 1970-01-01
    • 2016-11-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多