httmock在运行tox时不拦截requests.send()

时间:2014-03-01 03:30:10

标签: python http python-requests

我正在使用来自PyPI(https://pypi.python.org/pypi/httmock/)的httmock来捕获REST请求并模拟它们。我将在我的单元测试代码中使用它:

with httmock.HTTMock(my_request.token, my_request.put):
    payload = {'host-name': 'TestHost'}
    content = client.put_request('global/host-name',
                                  payload=payload)

作为put_request()的一部分,客户端类将看到没有身份验证令牌,并将首先发送带有用户和密码的POST请求以获取令牌,然后执行PUT请求。有断言检查过程的结果。

我有一大堆测试,当我使用tox运行它们时,这些测试工作得很好。但是,如果我运行完整的tox测试套件,我有大约30个测试失败。他们都没有通过身份验证。

我将debug添加到了httmock.py文件的副本和客户端代码中。我看到的是,在输入(),它接受requests.Session.send并保存它,替换为一个截断的函数,如预期的那样。但是,我从来没有看到在这些失败案例中调用的_fake_send()(没有看到日志消息)。因此,它没有返回任何内容(不是令牌),测试失败。

这里有一些带注释的日志记录:

1 DEBUG [drivers.httmock] Have 2 handlers
2 DEBUG [drivers.httmock] Enter requests.sessions
3 DEBUG [client] Authenticating with 'localhost'
4 DEBUG [client] POST: Request for .../api/v1/auth/...
5 DEBUG [client] >>> module drivers.httmock
6 DEBUG [client] POST Took 0.00 seconds to process
7 DEBUG [client] POST: Completed [401]
8 ERROR [client] Failed authentication with localhost [401]

[1]显示with子句注册了两个处理程序。 [2]在dunder输入上下文管理器并且requests.Session.send指向正常的模块/功能。 [4]是调用requests.request()之前的客户端。 [5]显示requests.Session.send已被交换到httmock。我希望看到[6]的日志为httmock尝试处理程序,但我看到客户端消息显示调用已完成。

我查看了请求库,request()创建了一个会话,并按预期调用了session.Session.send()。

我不是肯定的,但我认为在完整套件运行中,tox将并行运行测试。

任何人都有关于我可能做错的想法吗?

1 个答案:

答案 0 :(得分:1)

发现httmock使用假方法交换session.send(),该方法尝试为上下文管理器定义的各种处理程序。

我的代码正在调用requests.request(),它创建一个新会话,调用session.request(),调用session.send(),并且mock没有拦截send()调用。

我的猜测这是因为如果使用请求。* API,请求会为每个调用启动一个新会话。发现我的生产代码可以创建一个请求Session,然后为每个调用使用相同的会话(并使用session的request()方法而不是requests.request()方法)。

一旦完成,现在可以在完整的tox运行中运行,BTW使用多个线程来运行测试方法(在方法级别进行线程处理)。