6

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!

0

1 Answer 1

15

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%
Sign up to request clarification or add additional context in comments.

4 Comments

That's very detailed! Thank you!
Very good answer!! However I believe the second test function should be called test_member_failure instead of test_member_failure.. There are two test_member_success functions.
@Diana Yes, I just copy and paste the first test case code, forget to change the name:)
Nice clear code / answer. My question is, how do I mock multiple HTTP requests in the same unit test method? Don't expect an updated answer on this old question, tho :--).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.