How to mock a http request post in python unittest

Question:

First time write unittest.
Production code:

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...)

I need to test member. And I have test 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...)

Every time I run test, it always raises ValueError()(which is a 403 error)

How can I bypass that requests.post and just get a 201?

Thank you!

Asked By: maggie3003

||

Answers:

See Where to patch. And, you should provide a mock return value for the mock_post using return_value – The value returned when the mock is called.

E.g.

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


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

Test result:

.
----------------------------------------------------------------------
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%
Answered By: slideshowp2