python - 为什么最简单的 requests_mock 示例在 pytest 中失败?

标签 python mocking python-requests pytest

我对 requests_mock 有一个特殊的问题。我想将它与 pytest 一起使用来测试我的 API 包装器库。

我尝试使用 first example in the requests_mock docs , 除了我把它放在 test_mock() 函数中并添加了一个 assert 语句让 pytest 发现它。

以下代码失败:

# tests/test_mock.py

import requests
import requests_mock

with requests_mock.Mocker() as m:
    def test_mock():
        m.get('http://test.com', text='resp')
        assert requests.get('http://test.com').text == 'resp'

然而,当在 ipython 中运行以下示例时,它按预期工作。这是来自 example 的确切代码:

with requests_mock.Mocker() as m:
    m.get('http://test.com', text='resp')
    print(requests.get('http://test.com').text)

# prints 'resp'

因为我可以使 requests_mock 从 ipython 工作,所以我假设问题出在 pytest 上,但我可能错了。

似乎根本没有使用适配器,因此 requests 向目标 url 发送了一个真正的 http 请求,而不是使用模拟对象。


我正在使用 Python 3.6.3 (Anaconda3)、requests_mock 1.3.0 和 pytest 3.3.0

运行失败代码的输出:

C:\dev\mylib>pytest -v
============================= test session starts =============================
platform win32 -- Python 3.6.3, pytest-3.3.0, py-1.5.2, pluggy-0.6.0 -- e:\anaconda3\envs\benv\python.exe
cachedir: .cache
rootdir: C:\dev\mylib, inifile: setup.cfg
collected 1 item

tests/test_mocks.py::test_mock FAILED                                    [100%]

================================== FAILURES ===================================
__________________________________ test_mock __________________________________

    def test_mock():
        m.get('http://test.com', text='resp')
>       assert requests.get('http://test.com').text == 'resp'
E       assert '<!DOCTYPE ht...y>\n</html>\n' == 'resp'
E         + resp
E         - <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
E         - <html>
E         - <head>
E         - <title>Client Validation</title>
E         - <script type="text/javascript">
E         - function setCookie(c_name, value, expiredays) {...
E
E         ...Full output truncated (26 lines hidden), use '-vv' to show

tests\test_mocks.py:9: AssertionError
------------------------------ Captured log call ------------------------------
connectionpool.py          208 DEBUG    Starting new HTTP connection (1): test.com
connectionpool.py          396 DEBUG    http://test.com:80 "GET / HTTP/1.1" 302 161
connectionpool.py          824 DEBUG    Starting new HTTPS connection (1): www.test.com
connectionpool.py          396 DEBUG    https://www.test.com:443 "GET / HTTP/1.1" 200 None
========================== 1 failed in 2.05 seconds ===========================

最佳答案

为什么它在 IPython 中有效对我来说似乎是个谜。要解决此问题,只需将函数定义的行与上下文管理器的打开交换即可。

# tests/test_mock.py

import requests
import requests_mock

def test_mock():
    with requests_mock.Mocker() as m:
        m.get('http://test.com', text='resp')
        assert requests.get('http://test.com').text == 'resp'

关于python - 为什么最简单的 requests_mock 示例在 pytest 中失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47703748/

相关文章:

python - 从Python并行批量读取文件

bash - 如何编写可单元测试的 bash shell 代码?

python - 为什么我在尝试抓取特定网站时会收到 "Connection aborted"错误?

python - Scrapy - 如何存储下载图像的本地路径?

python - 使用 Python 循环使用随机范围的列表

python - 如何强制库(pybind11)包含Python3中的<Python.h>?

java - 如何使用 Mockito 通过私有(private)方法调用测试 void 方法

c# - 将项目从使用模拟对象和真实对象切换的模式

python - 在使用 python 请求下载之前获取 mp4 文件大小

Python:尝试发送大文件时, 'MultipartEncoder' 对象不可迭代