Is it possible to mock methods of imported modules with unittest.mock in Python 3.5?
# file my_function.py
import os
my_function():
# do something with os, e.g call os.listdir
return os.listdir(os.getcwd())
# file test_my_function.py
test_my_function():
os = MagickMock()
os.listdir = MagickMock(side_effect=["a", "b"])
self.assertEqual("a", my_function())
I expected that the the os.listdir method returns the specified side_effect "a" on the first call, but inside of my_function the unpatched os.listdir is called.
unittest.mock
have two main duties:
Mock
objects: object designed to follow your screenplay and record every access to your mocked objectIn your example, you need both functionalities: Patching os.listdir
reference used in production code by a mock where you can have complete control of how it will respond. There are a lot of ways to use patch
, some details to take care on how use it and cavelets to know.
In your case you need to test my_function()
behaviour and you need to patch both os.listdir()
and os.getcwd()
. Moreover what you need is control the return_value
(take a look to the pointed documentation for return_value
and side_effect
differences).
I rewrote your example a little bit to make it more complete and clear:
my_function(nr=0):
l = os.listdir(os.getcwd())
l.sort()
return l[nr]
@patch("os.getcwd")
@patch("os.listdir", return_value=["a","b"])
def test_my_function(mock_ld, mock_g):
self.assertEqual("a", my_function(0))
mock_ld.assert_called_with(mock_g.return_value)
self.assertEqual("a", my_function())
self.assertEqual("b", my_function(1))
with self.assertRaises(IndexError):
my_function(3)
I used the decorator syntax because I consider it the cleaner way to do it; moreover, to avoid the introduction of too many details I didn't use autospecing that I consider a very best practice.
Last note: mocking is a powerful tool but use it and not abuse of it, patch just you need to patch and nothing more.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With