Assertions
00:00
Now that you’ve seen the flexibility of Mock
objects, let’s start to see how we can use its built-in methods to gain deeper insight into our program. I’ve cleaned up this mock.py
file.
00:12
You can clear yours out or make a new file, and let’s import json
again, and let’s go under the assumption that we want to patch the json
module and some of its methods.
00:23
So we’ll say json
is a Mock
object, and then let’s pretend that somewhere in our program, we use the json.dumps()
method.
00:34
So we’ll say json.dumps()
and we’ll just put in a very simple dictionary here with 'a'
as the key and 1
as the value. And let’s remind ourself what is available, what methods come with this Mock
object.
00:49
So we’ll print the dir()
representation of json
, which is now just an instance of the Mock
class, and go down into the terminal and see what we can use.
01:00
I see a bunch of assert methods and some other methods. Let’s go ahead and play with some of these and see what they do. Let’s start with 'assert_called'
.
01:11
I’m going to delete this print(dir())
representation, and we’ll say json.dumps.assert_called()
. When you originally printed this dir()
representation, it was the representation of json
.
01:30
But remember that when you call a method on a Mock
object, it creates an instance of another Mock
object, so the dir()
representation of json.dumps
will also have this .assert_called()
method because it is a Mock
object as well.
01:49
Let’s save this program and run it—mock.py
.
01:56
And it doesn’t print anything because I didn’t print it. So we’ll just wrap a print()
around there and run the program again, and we’ll see a return value of None
.
02:08
So this return value of None
is essentially saying that “Yes, json.dumps()
was called,” because on line 5 we called the method json.dumps()
. Let’s try a different one.
02:21
So I’m going to copy this, paste it. And another method we have here is 'assert_called_once'
. So we’re going to change this to .assert_called_once()
, save it, and let’s clear the screen, and we’ll run the program again.
02:39
And we get another None
. So I interpret this as basically, like, true. So it was called once because on line 5, we called it once. Now let’s try to break this and we’ll repeat this line here, so we’re actually calling json.dumps()
twice.
02:59
Now we’ll save this and run the program again, and this time we get an AssertionError
. It says Expected 'dumps' to have been called once.
But it’s Called 2 times.
Now you may start to see why this is really valuable and useful in your tests, because sometimes you will want to test that your methods or your functions are only called a certain number of times.
03:23
I’m going to clear the screen, and let’s look at another assertion method. We’ll copy line 9 and we’ll change this to .assert_called_with()
. This assertion method allows you to check and verify that your functions are called with the parameters that you expect them to be called with. So first, let’s try to make this pass the test, so to speak.
03:46
So we originally called this json.dumps()
with this parameter. Let’s say we want to assert that it was called with this dictionary of {'a': 1}
.
03:59
Let’s go ahead and just—well, we’ll delete one of these json.dumps()
, just so we don’t get that exception from the .assert_called_once()
.
04:07
And let’s test out this new method here, .assert_called_with()
, with these specific parameters.
04:14
Let’s run our program and we get a None
, so that seems to be true. And then let’s try to break this, and we’ll just change the value to 2
.
04:25 We’ll go down and clear the screen, run the program again,
04:29
and there we get another AssertionError
. So, Expected call
to be with the value of 2
, and we actually got a value of 1
.
04:38
This is very helpful information when you run your tests to see that you’re using your functions as you should be. You’ve looked at some of the assertion methods associated with Mock
objects.
04:53
In the next video, you’ll see and play with some of the other attributes that come with Mock
objects.
abdelmalek13 on Aug. 5, 2021
I think it’s just to show us, but nah, no one prints an assert statement
al on Jan. 10, 2023
I don’t get why did you even had to import json in this example. If we are never really using the “real” json, but just whatever Mock() returns, then we shouldn’t need to import the real thing in the first place anyways.
Also, I never once had to check if/how many times a certain method was called. Testing results is a more common use-case. But anyways… that’s minor.
Bartosz Zaczyński RP Team on Jan. 11, 2023
@al Right, you don’t need to import the json
module in this case. You would if you wanted to create a mock mirroring the API:
>>> import json
>>> from unittest.mock import Mock
>>> mock_json = Mock(json)
>>> dir(mock_json)
['JSONDecodeError', 'JSONDecoder', 'JSONEncoder', ..., 'dump', 'dumps', 'encoder', 'load', 'loads', ...]
Notice that the resulting mock object has the same functions and attributes as the original module.
Vijay Iyer on Jan. 21, 2023
Why doesn’t assert_called_once return True or False? Wouldn’t that be how it’s used?
Bartosz Zaczyński RP Team on Jan. 23, 2023
@Vijay Iye Assertions are typically hooked in some way to the testing framework like Python’s unittest, so when an assertion fails, then it notifies the test runner by raising an AssertionError
. If an assertion just returned a True
or False
value, then the test result wouldn’t have been correctly picked up and reflected in the test report.
Become a Member to join the conversation.
Steve Wehba on Aug. 16, 2020
I don’t understand why you’re printing the return value of your assertions. Never seen anybody do that in a test case before. Is there some reason you’re doing that?