如何在 python unittest 中模拟 http 请求帖子

mag*_*003 6 python python-requests 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...)
Run Code Online (Sandbox Code Playgroud)

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

@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...)
Run Code Online (Sandbox Code Playgroud)

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

我如何绕过 requests.post 并只得到 201?

谢谢你!

sli*_*wp2 12

请参阅修补位置mock_post并且,您应该为使用提供模拟返回值return_value - 调用模拟时返回的值。

例如

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
Run Code Online (Sandbox Code Playgroud)

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_failure(self, mock_post):
        mock_post.return_value.status_code = 400
        self.assertRaises(ValueError, member, 1)


if __name__ == '__main__':
    unittest.main()
Run Code Online (Sandbox Code Playgroud)

测试结果:

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

OK
Name                                        Stmts   Miss  Cover   Missing
-------------------------------------------------------------------------
src/stackoverflow/70098351/member.py           11      2    82%   18, 23
src/stackoverflow/70098351/test_member.py      11      0   100%
-------------------------------------------------------------------------
TOTAL                                          22      2    91%
Run Code Online (Sandbox Code Playgroud)