Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mock a method of a mocked object in Python?

I am writing unit tests for a project written in Python 3.4, using the unittest.mock library. The function I am testing contains a call to a function

versions = get_all_versions(some_argument)

which I have patched with a MagicMock object that returns a list, so that version becomes a list of version numbers, which all works fine.

Now, the code I am testing has changed a bit, and looks like

versions = get_all_versions(some_argument).order_by(another_argument)

Now I need the order_by method to return the same list of version numbers, while get_all_versions should remain mocked, and I have some problems achieving this.

I have tried patching it with

get_all_versions = MagickMock() get_all_versions.order_by = version_list

but that does not work, and I guess it is because order_by is a method and not a property. I have also tried

get_all_versions = MagicMock() get_all_versions.order_by = MagicMock(return_value=version_list)

and (more desperately)

get_all_versions = MagicMock(return_value=MagicMock(return_value=version_list)) but neither of those two work.

How do I mock a function that returns an object, and then mock a method of that object so that it returns a list?

like image 502
Syntaxén Avatar asked Nov 23 '17 09:11

Syntaxén


People also ask

What does mock mock () do?

The Mockito. mock() method allows us to create a mock object of a class or an interface. We can then use the mock to stub return values for its methods and verify if they were called. We don't need to do anything else to this method before we can use it.

What is the difference between mock and MagicMock?

Mock vs. So what is the difference between them? MagicMock is a subclass of Mock . It contains all magic methods pre-created and ready to use (e.g. __str__ , __len__ , etc.). Therefore, you should use MagicMock when you need magic methods, and Mock if you don't need them.


1 Answers

What you want is to have get_all_versions return an object that has a method order_by which returns version_list:

get_all_versions = MagicMock()
get_all_versions.return_value.order_by.return_value = version_list

To explain why your attempts didn't work, your first attempt replaces the method order_by with the value version_list:

get_all_versions = MagicMock()
get_all_versions.order_by = version_list

The result of this is roughly this:

get_all_versions.order_by == version_list

The second attempt replaces the return value of get_all_versions with something that looks like a function and returns version_list:

get_all_versions = MagicMock(return_value=MagicMock(return_value=version_list))

This results in:

get_all_versions(some_argument)(another_argument) == version_list

I hope this clears things up!

like image 70
Kendas Avatar answered Oct 10 '22 19:10

Kendas