如何在 python 单元测试中模拟 http 请求 post

How to mock a http request post in python unittest

第一次写单元测试。 生产代码:

def get_session_token(organization_id):
    endpoint = get_endpoint(organization_id)
    response = requests.post(
        endpoint + "/some/url/part",
        data=json.dumps({
            "Login": CONFIG[organization_id]["username"],
            "Password": CONFIG[organization_id]["password"],
        }),
        headers={"Accept": "application/json"}
    )

    if response.status_code != 201:
        log.error("filename.get_session_token(%r): couldn't auth: %r %r",
                  organization_id, response, response.text)
        raise ValueError()

    return response.json()

def member(organization_id):
    session_key = get_session_token(organization_id)
    (some other code...)

我需要测试会员。我有测试代码:

@patch('requests.post')
def test_member(self, mock_post):
    mock_post().status_code = 201
    mock_response = mock_post("some/url", data=ANY,
                              headers={"Accept": "application/json"})
    mock_response.status_code = 201
    (some other code...)

每次我 运行 测试时,它总是引发 ValueError()(这是一个 403 错误)

我怎样才能绕过 requests.post 并获得 201?

谢谢!

参见 Where to patch。并且,您应该使用 return_valuemock_post 提供模拟 return 值 - 调用模拟时的值 return。

例如

member.py:

import requests
import json


def get_session_token(organization_id):
    endpoint = 'http://localhost:3000/api'
    response = requests.post(
        endpoint + "/some/url/part",
        data=json.dumps({
            "Login": 'python',
            "Password": '123456',
        }),
        headers={"Accept": "application/json"}
    )
    if response.status_code != 201:
        raise ValueError()

    return response.json()


def member(organization_id):
    session_key = get_session_token(organization_id)
    return session_key

test_member.py:

from unittest.mock import patch
import unittest
import json
from member import member


class TestMember(unittest.TestCase):
    @patch('member.requests.post')
    def test_member_success(self, mock_post):
        mock_post.return_value.status_code = 201
        mock_post.return_value.json.return_value = 'mock response'

        actual = member(1)
        self.assertEqual(actual, 'mock response')
        mock_post.assert_called_once_with(
            'http://localhost:3000/api/some/url/part',
            data=json.dumps({
                "Login": 'python',
                "Password": '123456',
            }),
            headers={"Accept": "application/json"}
        )

    @patch('member.requests.post')
    def test_member_success(self, mock_post):
        mock_post.return_value.status_code = 400
        self.assertRaises(ValueError, member, 1)


if __name__ == '__main__':
    unittest.main()

测试结果:

.
----------------------------------------------------------------------
Ran 1 test in 0.001s

OK
Name                                        Stmts   Miss  Cover   Missing
-------------------------------------------------------------------------
src/Whosebug/70098351/member.py           11      2    82%   18, 23
src/Whosebug/70098351/test_member.py      11      0   100%
-------------------------------------------------------------------------
TOTAL                                          22      2    91%