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

  • Context: Python 
  • Thread starter Thread starter Swamp Thing
  • Start date Start date
  • Tags Tags
    Method Python
Click For Summary
SUMMARY

This discussion focuses on extracting method and object names from the method_calls attribute of a mock object in Python's unittest.mock library. Users can retrieve names such as 'thing', 'pop', 'bob', and 'smash' from the method_calls array, which contains call objects that mimic the hierarchy of the mocked functions. The call object returns a tuple where the first element is a string representing the called hierarchy, and the remaining elements are the arguments passed to the method. Understanding the structure of these call objects is essential for effective testing with mocks.

PREREQUISITES
  • Familiarity with Python 3 syntax and conventions
  • Understanding of the unittest.mock library
  • Knowledge of call objects and their structure in mocking
  • Basic string manipulation in Python, particularly using .split()
NEXT STEPS
  • Explore the unittest.mock documentation for advanced mocking techniques
  • Learn how to implement and use mock_calls for more complex scenarios
  • Investigate the differences between method_calls and mock_calls in unittest.mock
  • Experiment with nested mocks and their call hierarchies
USEFUL FOR

Python developers, software testers, and anyone utilizing the unittest.mock library for unit testing and mocking in their applications.

Swamp Thing
Insights Author
Messages
1,047
Reaction score
780
TL;DR
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 ·
Replies
10
Views
3K
  • · Replies 4 ·
Replies
4
Views
2K
  • · Replies 1 ·
Replies
1
Views
2K
  • · Replies 1 ·
Replies
1
Views
3K
  • · Replies 1 ·
Replies
1
Views
1K
  • · Replies 4 ·
Replies
4
Views
5K
  • · Replies 5 ·
Replies
5
Views
4K
  • · Replies 3 ·
Replies
3
Views
1K
Replies
3
Views
1K
  • · Replies 1 ·
Replies
1
Views
1K