Skip to content

Commit d376140

Browse files
committed
Add example code for mock resurfacing
1 parent c0b2da3 commit d376140

File tree

3 files changed

+119
-0
lines changed

3 files changed

+119
-0
lines changed

unittest-mock/README.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Understanding the Python Mock Object Library
2+
3+
This folder contains code examples related to the RealPython tutorial on [Understanding the Python Mock Object Library](https://realpython.com/python-mock-library/).
4+
5+
The example code showcases some of the different use cases of `unittest.mock` in a single test file, `test_my_calendar.py`. When writing your own tests, keep in mind that readability counts and that your test code will be better readable if you keep one consistent approach to mocking.
6+
7+
## Installation
8+
9+
1. Create a Python virtual environment
10+
11+
```sh
12+
$ python -m venv ./venv
13+
$ source venv/bin/activate
14+
(venv) $
15+
```
16+
17+
2. Install the requirements
18+
19+
```sh
20+
(venv) $ pip install requests
21+
```
22+
23+
## Run the Tests
24+
25+
```sh
26+
(venv) $ python test_my_calendar.py
27+
```
28+
29+
All the tests should pass. Go ahead and play with the code examples, change them, break them, and practice your understanding of using `unittest.mock` for testing in Python.
30+
31+
## About the Author
32+
33+
Martin Breuss - Email: [email protected]
34+
35+
## License
36+
37+
Distributed under the MIT license. See ``LICENSE`` for more information.

unittest-mock/my_calendar.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from datetime import datetime
2+
3+
import requests
4+
5+
6+
def is_weekday():
7+
today = datetime.today()
8+
# Python's datetime library treats Monday as 0 and Sunday as 6
9+
return 0 <= today.weekday() < 5
10+
11+
12+
def get_holidays():
13+
r = requests.get("http://localhost/api/holidays")
14+
if r.status_code == 200:
15+
return r.json()
16+
return None

unittest-mock/test_my_calendar.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import datetime
2+
import unittest
3+
from unittest.mock import Mock, patch
4+
5+
import requests
6+
from requests.exceptions import Timeout
7+
8+
from my_calendar import get_holidays, is_weekday
9+
10+
11+
class TestCalendar(unittest.TestCase):
12+
@classmethod
13+
def setUpClass(cls):
14+
cls.wednesday = datetime.datetime(year=2025, month=1, day=1)
15+
cls.sunday = datetime.datetime(year=2025, month=1, day=5)
16+
cls.holidays = {"12/25": "Christmas", "7/4": "Independence Day"}
17+
cls.response_setup_dict = {
18+
"json.return_value": TestCalendar.holidays,
19+
"status_code": 200,
20+
}
21+
22+
def log_request(self, url):
23+
"""Helper function that logs and returns a mock successful request."""
24+
print(f"Making a request to {url}.")
25+
print("Request received!")
26+
response_mock = Mock(**TestCalendar.response_setup_dict)
27+
return response_mock
28+
29+
@patch("my_calendar.datetime")
30+
def test_is_weekday_returns_true_on_weekdays(self, mock_datetime):
31+
mock_datetime.today.return_value = TestCalendar.wednesday
32+
self.assertTrue(is_weekday())
33+
34+
@patch("my_calendar.datetime")
35+
def test_is_weekday_returns_false_on_weekends(self, mock_datetime):
36+
mock_datetime.today.return_value = TestCalendar.sunday
37+
self.assertFalse(is_weekday())
38+
39+
# Example of patching only a specific object
40+
@patch.object(requests, "get", side_effect=requests.exceptions.Timeout)
41+
def test_get_holidays_timeout(self, mock_requests):
42+
with self.assertRaises(requests.exceptions.Timeout):
43+
get_holidays()
44+
45+
# Example of using the `with` statement with `patch()`
46+
def test_get_holidays_logging(self):
47+
with patch("my_calendar.requests") as mock_requests:
48+
mock_requests.get.side_effect = self.log_request
49+
self.assertEqual(get_holidays()["12/25"], "Christmas")
50+
51+
@patch("my_calendar.requests")
52+
def test_get_holidays_retry(self, mock_requests):
53+
response_mock = Mock(**TestCalendar.response_setup_dict)
54+
# Set the side effect of .get()
55+
mock_requests.get.side_effect = [Timeout, response_mock]
56+
# Test that the first request raises a Timeout
57+
with self.assertRaises(Timeout):
58+
get_holidays()
59+
# Now retry, expecting a successful response
60+
self.assertEqual(get_holidays()["12/25"], "Christmas")
61+
# Finally, assert .get() was called twice
62+
self.assertEqual(mock_requests.get.call_count, 2)
63+
64+
65+
if __name__ == "__main__":
66+
unittest.main()

0 commit comments

Comments
 (0)