Locked learning resources

Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Locked learning resources

This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

patch() as Decorator

00:00 Let’s open up this tests.py file and we’ll import the patch() function. This comes from unittest.mock import patch.

00:12 We’ll also just import unittest so we can write some unit tests. And let’s create our first test class, so we’ll say class TestCalendar, and this inherits from unittest.TestCase.

00:28 Let’s test our get_holidays() function. In order to do this, we need to import it into our tests file. So we’ll say from my_calendarthat’s the name of our module—we’ll import get_holidays.

00:48 And let’s do a similar test where we will mock the requests.get() to have a side effect of a Timeout. In order to have access to that Timeout exception, we’ll say from requests.exceptions import Timeout.

01:04 Then we’ll come into our TestCalendar class and create a function called .test_get_holidays_timeout() and this will take self. And we’ll write a function in here, but first let’s think about what we want to mock.

01:22 So, we want the effect of requests.get() to be a Timeout exception. But we haven’t mocked the requests module. The requests module is imported in my_calendar, so we’ve imported requests because we need it to make a GET request to our /holidays API.

01:43 What we want to do is mock this method requests.get() and have it raise a Timeout exception as a side effect. Let’s go back into tests.py and we’ll use the patch() function as a decorator to patch requests.get(). So above the test, we’ll decorate it with the @patch() function.

02:06 And the first argument here is the path to the module that we want to mock, and it’s represented as a string. The path first starts with the module—and that means our local module, my_calendar—so, 'my_calendar' and then the module object that we want to patch.

02:26 We want to patch the requests module—again, which we have imported in my_calendar. So we’re using @patch() to patch this particular object—let’s call it an object, just to be clear. This my_calendar is the module and we’re patching this requests object in our test.

02:45 And it’s important to know that this is now scoped to this particular test. Anything outside of this test will not have access to this requests mock.

02:57 And then we also need to pass it as an argument, so this next argument that I’m about to type is the mocked requests module. I’m just going to call it mocked_requests, just to be clear.

03:11 Now let’s set the .side_effect of the mocked_requests.get(). So we have that module available as mocked_requests, and we’ll say .get.side_effect is a Timeout.

03:26 And now we can write our test that verifies that when we call get_holidays(), it should raise a Timeout exception. So with self.assertRaises(Timeout): we’ll call get_holidays(). And then to run our test, we’ll create our entry point of if __name__ == '__main__': we’ll run unittest.main().

03:54 I’ll open up my terminal and let’s run python and give it tests.py.

04:02 Whoops. We have a little typo. 'my_calendar'so where did I type that? There we go. So be sure to make sure your spelling’s correct, but fortunately Python lets us know that it was not.

04:17 And there we go. Our test succeeded. We were able to patch the requests module—

04:27 the requests module object—coming from a different module.

04:32 So that means we don’t have to have any mock objects in our codebase—in our core codebase—and we can use patch() to send them into our tests.

Become a Member to join the conversation.