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

Unlock This Lesson

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

Unlock This Lesson

Hint: You can adjust the default video playback speed in your account settings.
Hint: You can set your subtitle preferences in your account settings.
Sorry! Looks like there’s an issue with video playback 🙁 This might be due to a temporary outage or because of a configuration issue with your browser. Please refer to our video player troubleshooting guide for assistance.

Side Effects: Advanced Test (Part 2)

00:00 So now that we have this kind of helper function, this .log_request() function within our test class, let’s write a test to test the response with a log statement.

00:13 We’ll make another function called def test_request_with_logging().

00:19 Just a side note here, the unittest module when we run unittest.main()it will look for the TestGetHolidays class and it will run functions that start with test_.

00:34 We want to make a GET request to our API, so we’re going to say requests.get.side_effect, and here instead of passing an exception or something, we’re going to pass this .log_request() function.

00:51 And rather, this is a self.log_request(), because it’s inside the class.

00:57 So this is a little magical. First off, remember that requests is not the actual requests module—it is a Mock object.

01:08 We’ve mocked requests and therefore .get() is going to be a Mock object and then .side_effect is this function.

01:18 So one tricky thing here is that when we set the .side_effect to a function, it’s going to inherit its arguments and its return value. So in other words, when we say requests.get(), remember that originally, the arguments of requests.get() is going to be this URL.

01:45 So since requests is a Mock object, we’re saying rwhich is requests.get()—this argument. So down in our test here, we already have access to that URL endpoint,

02:02 and that is going to be forwarded to this function since we’ve defined it as the .side_effect. So in a way, it kind of looks like we’re calling this function with this 'localhost/api/holidays'.

02:21 And I know it’s a little confusing, but it’s just something that you have to know and kind of roll with, is that requests.get()which we’ve set up here in our get_holidays() function—has this argument passed in into it, so to speak.

02:40 So when we make that GET request inside get_holidays(), we’re setting the .side_effect to this function, our .log_request() function.

02:55 So that means we can do something like assert get_holidays()so we call that function—and this should now have a response. So we’re mocking the request and we have the .status_code at 200, so that means that get_holidays() is going to drop into this block and return .json(), which we have mocked here—we’ve mocked the .return_value as this dictionary.

03:23 So we should be able to assert that get_holidays() is going to return a dictionary, and let’s check that the 25th of December is equal to 'Christmas'.

03:36 Let’s see if this actually works now. I’m going to open up a terminal and we will run our tests. Since we have this unittest.main(), it should pick up these three tests that start with test_. In the previous video, we already saw that these should pass, so let’s go ahead and cross our fingers and see if our new test passes.

03:58 So we’ll say python run my_calendar.py.

04:04 All right, it passed! It Ran 3 tests and we also see our log statement here.

artemudovyk on April 13, 2022

It’s was a little bit hard to understand why we should use side_effect instead of return_value.

Found this answer that made it clear:

With side_effect you define a function/class (or iterator or exception), which should be called instead of the original function/class. With return_value you define the result, what the function/class is supposed to return so that we don’t need to call it.`

Jakub Urbánek on Nov. 25, 2022

For some reason my code is not working. Double checked twice, should be exactly the same, but doesn’t work. Is there any file to download with the whole code?

Bartosz Zaczyński RP Team on Nov. 29, 2022

@Jakub Urbánek Yes, you can click on Supporting Materials | Sample Code from the dropdown just below the video, or grab this link directly: realpython.com/courses/python-mock-object-library/downloads/code-mock/

Become a Member to join the conversation.