Understanding Unittest.Mock

Creating Complex Mocks

Your browser needs to be JavaScript capable to view this video

Try reloading this page, or reviewing your browser settings

This segment describes how the automatic creation of child mocks on attribute access work and why it is useful, especially for tests where we want a dummy.

Keywords

  • child
  • mock
  • automatic
  • attribute
  • dummy

About this video

Author(s)
Mario Corchero
First online
25 December 2018
DOI
https://doi.org/10.1007/978-1-4842-4413-5_3
Online ISBN
978-1-4842-4413-5
Publisher
Apress
Copyright information
© Mario Corchero 2019

Video Transcript

In this segment, we’re going to see some more complex features of mock. We’re going to see how to use kwargs to create change of mocks. We’re going to see how, um, a feature called child mock creation help us create, um, you know, mocks, uh, in a real easy way. And then we’ll see what’s the difference between mocks and MagicMocks. Okay. So we saw how to create mocks using unittest.mock. But we’re going to see how can we create them in a much lean way because when we want to create more complex mocks, it would be still too much boilerplate to create them this way. So we saw that, you know, we wanted to create this, um, uh, testing double that will, um, be used to… used for that function that we just described before. We could do it like that. I’m just, you know, created a mock which is the fake_response created in segment 1. That was the fake_session, but if we want, we could create this single line. So we could create a fake_session and then this fake_session, it’s, uh, it’s a mock and it… it’s going to take a keyword argument, the whole chain that it want to do. And to so, because we cannot just do it, because if there is a retrict, uh, set of chracters that we can put in a keyword the argument, what we do is we expand a dictionary that we’re going to pass. But first of all, uh, we need to define, you know, the step payload, response_payload. Payload. And that’s what we want at the end of the change to be called whenever we have the response, we call get on the response. We have… and then response… the response get returns in object and that object is being called in JSON and JSON is going to return this response payload. So if we want to do that, all we have to do is pass dictionary were the key is old that… so we do, um, so now your fake_session, so we do, uh, get.return_value, right? Yes, that’s what… this is going to be a mock. And the get.return_value it’s going to be when it’s being called .json.return_value is going to give us the whole change. And this, this can be the response_payload. This is going to create our mock in this line. So this is a great way to create more complex mocks. And I’m sorry, I haven’t imported mock before there you go. And now we have, uh, this fake_session that when we call the get on end, we can see that that returns the mock. So effectively, this part here has generated the mock for us. And when we called JSON on it, it’s going to return the response we expected. Now to be fair, this way is really powerful, this way of creating mocks. But there’s, uh, a way that I prefer and use the value that mocks, when they are called, it will automatically create another mock. What do I mean with that, so I meant, if you do fake_session and now this is a mock, mocks will automatically create mocks when they are called. Is that confusing? Let’s see an example. So of you do fake_session.attribute1.meth od2 and you call it, this returns you a mock. What this means is when you do .attribute, the .attribute is giving you a mock then you do .method2, that’s giving you another mock, and then you call it, that is giving you another mock back. Why is this useful? This is useful to define them. So we can do… we can just do the way that’s going to be called, so fake_session.get.return_value .json.return_value. That is the mock that we want. So all we have to do is assign the response_payload in. Uh, let me copy-paste. I have a typo there. And now if we call again to this chain, that’s what’s going to be called in the method, we can see that we get the same response. So whether we do it this way or this way, we can define the whole interface for mock and, you know, all the results of its called in a single line. One more thing to highlight from the mock library is, uh, the MagicMocks. So MagicMocks are basically mocks with magic methods. And what that means is that, uh, MagicMocks will allow you to, um, not only call them and access them, but also use operations on them that are defined by magic methods. And what we mean by this is that if we have… if we have… if we try to, um, access an item for mock, that will… that won’t work if we try to use a mock like dictionary, uh, it won’t work. If we try to, um, add something to a mock, this won’t work. And this is all because, um, for this things to work, we would have… we would need the mock to define, for example here and, um, ._add operation if you were to define that function, it will work. And for that purpose, we have, uh, MagicMocks. So instead of a mock, we use the MagicMock that we define here. This will work automatically returning us another MagicMock as we would have expected, same happens when, uh, when we use it here and, uh, same with all the operations. Um, note that this also propagates, uh, as we saw before when mock will create, uh, child mocks. So if we do attribute.method, uh, plus 1, this will still work on the MagicMock. We can see here the whole chain of call. Uh, same applies for older situations like for example, like, uh, um, truediv. This basically will allow us by using the MagicMock to let the function where passing it call any… anything that will require magic method to be present. The only magic method that’s special and is implemented in mock is… had undergo and that’s because, uh, it was… it’s what’s going to drive him what the… what the mock’s going to return whenever we call it.