8000 Merge branch 'master' into python-protocol · realpython/materials@7f9a3e4 · GitHub
[go: up one dir, main page]

Skip to content

Commit 7f9a3e4

Browse files
authored
Merge branch 'master' into python-protocol
2 parents 7876c95 + 53c2052 commit 7f9a3e4

File tree

3 files changed

+117
-0
lines changed

3 files changed

+117
-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_holidays.py`. When writing your own tests, keep in mind that readability counts and that your test code will be more 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_holidays.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: martin@realpython.com
34+
35+
## License
36+
37+
Distributed under the MIT license. See `LICENSE` for more information.

unittest-mock/holidays.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_holidays.py

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

0 commit comments

Comments
 (0)
0