Reputation: 536
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 = MagicMock()
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?
Upvotes: 31
Views: 18144
Reputation: 2253
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!
Upvotes: 29