2

我将pytest-mock 包装器与 pytest 一起使用。

我无法让 PropertyMock 与requests 包一起工作。

这是我尝试进行单元测试的函数示例:

def get():
    url = f'http://foo.bar/'
    response = requests.get(url)
    if response.status_code != 200:
        sys.exit(1)
    return response.text

这是我在单元测试中的尝试:

import pytest
import my_module
import requests

def test_get(mocker, monkeypatch):
    response_mock = mocker.MagicMock()
    status_code_mock = mocker.PropertyMock(return_value=200)
    text_mock = mocker.PropertyMock(return_value='xyz')
    type(response_mock).status_code = status_code_mock
    type(response_mock).text = text_mock
    monkeypatch.setattr(requests, 'get', response_mock)

    my_module.get()

测试失败,因为 200 没有返回response.status_code

我尝试在调用后放置一个 PDB 断点requests.get(),并自己在 PDB 中检查了 response.status_code 属性。我得到一个 MagicMock 对象:

(Pdb) response.status_code
<MagicMock name='mock().status_code' id='4487925656'>
4

1 回答 1

1

它是分配给变量的调用的返回值。requests.getresponse

在这一行:

monkeypatch.setattr(requests, 'get', response_mock)

您用模拟替换了 get 方法本身。但是你可能想要的是用调用时返回你的响应模拟的东西来替换它,例如:

monkeypatch.setattr(requests, 'get', lambda url: response_mock)

顺便说一句,请考虑为此代码使用现有的 pytest 插件/装置。requests_mock并且responses都是不错的选择。之后pip install requests_mock,例如,您的测试可能看起来像这样:

def test_get_better(requests_mock):
    requests_mock.get("http://foo.bar/", text="xyz")
    response_text = my_module.get()
    assert response_text == "xyz"
于 2019-05-11T00:13:55.403 回答