【问题标题】:Import issue while mocking REST in py.test在 py.test 中模拟 REST 时导入问题
【发布时间】:2017-12-04 14:29:55
【问题描述】:

我尝试用 Python 为 REST 客户端编写一些单元测试。我无法模拟来自服务器的响应。 具体来说,我希望 GET 查询返回一个预先准备好的 JSON 字符串,而不连接到服务器。正如我了解到的那样,在 Python 中执行此操作的方法是使用 unittest.mockpytest-mock。我的项目结构是这样的:

workspace/__init__.py
workspace/module/__init__.py
workspace/module/connector.py
workspace/tests/__init__.py
workspace/tests/test_connector.py

我把测试代码放在test_connector.py。我试过以这种方式使用unittest.mock.patch

@patch()
test_get_container_list(mocker):
    (....)

还有pytest-mock:

mocker.patch('module.connector.Connector.get_container_list.requests.sessions.get')
mocker.return_value.ok = True
mocker.return_value.json.return_value = container_list

我被这个错误难住了:

ImportError: No module named 'module.connector.Connector'; 'module.connector' is not a package

我也尝试修改我在路径中放置的内容,但我得到的只是:

ImportError: No module named 'Connector'
ImportError: No module named 'connector.Connector'; 'connector' is not a package

我用这个命令启动了测试:

pytest 测试/

来自module 目录。我的导入看起来像这样:

import configparser
import pytest
from module.connector import Connector

环境:Ubuntu 16.04、Python 3.5.2、pytest-3.2.5、py-1.5.2、pluggy-0.4.0;插件:mock-1.6.3、cov-2.5.1

所有剩余的测试都没有问题,只有这个带有模拟的测试没有。

我的问题:如何使模拟测试正常工作? (无论我使用pytest-mock 还是unittest.mock,都会出现导入错误)。

【问题讨论】:

  • 删除workspace/__init__.py 文件?你需要workspace 成为一个包吗?
  • __init__.py 在那里不需要,但删除它没有帮助。
  • 您的问题显然不是 pytest 或 mocking,您在导入解析时遇到了问题。如果我重新创建您描述的设置(module 中的workspace dir、moduletestsConnector 包,我可以在测试中导入该类并通过unittest.mock、@987654344 对其进行修补@ 或monkeypatch。所以这显然不是问题。另外,这个:我用这个命令启动了测试:pytest tests/ 从模块目录不能用你描述的目录结构运行。

标签: python python-3.x mocking pytest


【解决方案1】:

我走了另一条路,我没有使用pytest-mock,而是使用了request-mock。这里的方法是使用requests 正常执行HTTP 请求并模拟特定URL 的响应。

import requests
import requests_mock

def test_requests():
    with requests_mock.Mocker() as mock:
        session = requests.Session()
        url = 'https://google.com/'

        mock.register_uri('GET', url, text='{"answer": "My return text"}')  # mocking the http response within this context
        resp = session.get('https://google.com/')
        assert resp.json()['answer'] == 'My return text'

查看更多信息 here 并且您可能想要查看请求匹配 here

希望这能给您一些替代方法的灵感。

【讨论】:

    【解决方案2】:

    我认为这个问题可能是 Pytest 和导入的问题,基本上每个人(包括我自己)似乎都有,从我在这里遇到的类似问题的数量来看。

    This answer 对我特别有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-12-08
      • 2019-06-08
      • 2019-02-22
      • 2012-01-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多