Python Python, unittest.mock : Getting object & method names from method_calls

  • Thread starter Thread starter Swamp Thing
  • Start date Start date
  • Tags Tags
    Method Python
AI Thread Summary
To extract method and object names from `my_mock.method_calls`, you can access the first element of each call, which is a string representing the hierarchy of the call. The call object mimics the structure of the mocked object, allowing for easy retrieval of names like 'thing', 'pop', 'bob', and 'smash'. This behavior is due to the 'tupleness' of the call object, where the first element contains the hierarchy as a string. When dealing with multiple mocks, each mock's method_calls will generate distinct call objects, even if they reference the same method names. Experimentation is encouraged to fully understand the nuances of the call object and its structure.
Swamp Thing
Insights Author
Messages
1,028
Reaction score
768
TL;DR Summary
Finding object and method names from the elements of some_mock.method_calls when using unittest.mock
Let's say that my_mock.method_calls gives me this array:

Code:
[call.thing.pop(3, 4), call.thing.bob.smash(6, 7), call.thing.jig.slurp(4)]

How can I extract the names 'thing', 'pop', 'bob', 'smash' etc. from this array?
 
Technology news on Phys.org
I don't quite understand how this works, but it does. In your linked doc, they give an example to retrieve names from mock_calls. But I tried it for method_calls and it works just as well.

It's rather counterintuitive:
Code:
>>> my_mock.method_calls[1]
call.thing.bob.buzz(6, 7)
>>> my_mock.method_calls[1][0]
'thing.bob.buzz'

Looking at lines 1 and 2, I would have thought that my_mock.method_calls[1][0] would print 6... but no, it evaluates to 'thing.bob.buzz'.

I guess it has to do with the 'tupleness' of the call object, as the doc puts it.

Anyway, it works... Thanks!
 
I'd like to understand the philosophy behind this functionality.

At the moment my notion is this:- "When we invoke a method on a (possibly nested) mock object, then the call object acquires its own parallel inner hierarchy in which the names mimic those in the called hierarchy. This hierarchy within call terminates in a method, which again has the same name as the mocked function that was called. But this method within call, when we call it, returns a tuple in which the first element is a string that tells us the called hierarchy. The remaining elements are the respective called arguments"

Is the above correct?

But in that case, what kind of beast is the object named "call"? Is it a global object that spans the entire test?
What if we have two mocks, mock1 and mock2, and we call mock1.thing.pop() and mock2.thing.pop ..?

In that case, mock1.method_calls and mock2.method_calls will both evaluate to call.thing.pop(). Would those two call objects be the same thing or different things?
 
Swamp Thing said:
what kind of beast is the object named "call"? Is it a global object that spans the entire test?
What if we have two mocks, mock1 and mock2, and we call mock1.thing.pop() and mock2.thing.mock ..?

In that case, mock1.method_calls and mock2.method_calls will both evaluate to call.thing.pop(). Would those two call objects be the same thing or different things?
These are the sorts of questions that are best answered by experimenting.
 
jedishrfu said:
Are they strings like xxx.yyy.zzz where you can split them into a string array via the .split(".") method?
Yes. That is, the first element of call.thing.pop() is a string of that sort.
 

Similar threads

Replies
10
Views
3K
Replies
4
Views
2K
Replies
1
Views
1K
Replies
4
Views
5K
Replies
1
Views
1K
Back
Top