I am trying to get mock.patch to work on the following piece of sample code:
from mock import patch from collections import defaultdict with patch('collections.defaultdict'): d = defaultdict() print 'd:', d
This outputs the following:
d: defaultdict(None, {})
Which means that defaultdict was not patched.
If I replace the from/import statement with a straight import statement it works:
from mock import patch import collections with patch('collections.defaultdict'): d = collections.defaultdict() print 'd:', d
Output is:
d: <MagicMock name='defaultdict()' id='139953944084176'>
Is there any way to patch a call using from/import?
Thank you
Rather than hacking on top of Python's import machinery, you can simply add the mocked module into sys. path , and have Python prefer it over the original module. Now, when the test suite is run, the mocked-lib subdirectory is prepended into sys. path and import A uses B from mocked-lib .
mock provides a powerful mechanism for mocking objects, called patch() , which looks up an object in a given module and replaces that object with a Mock . Usually, you use patch() as a decorator or a context manager to provide a scope in which you will mock the target object.
Mock is a type, and patch is a context. So you are going to pass or receive Mock instances as parameters, and apply patch contexts to blocks of code. (Lowercase 'mock' is just the name of the package.) Tests and test classes are often decorated with calls to patch.
5 I found fine way to mock the imports in Python. It's Eric's Zaadisolution found herewhich I just use inside my Djangoapplication. I've got class SeatInterfacewhich is interface to Seatmodel class.
Or you can just assign a Mock()directly: test.py: import sys sys.modules['B'] = Mock() import A Share Improve this answer
20 How to mock an import, (mock A.B)? Module A includes import B at its top. Easy, just mock the library in sys.modules before it gets imported: if wrong_platform(): sys.modules['B'] = mock.MagicMock() and then, so long as Adoesn't rely on specific types of data being returned from B's objects: import A should just work.
We must note that, we patch only where an object is looked up, which is not necessarily the same place as where it is defined. For example, consider following project structure that we want to test: Now, we want to test a_func but we want to mock out AClass using patch ().
If you're patching something in the same module, you can use __main__
:
from mock import patch from collections import defaultdict with patch('__main__.defaultdict'): d = defaultdict() print 'd:', d
If you're mocking something for an imported module, however, you'll want to use that module's name so the correct reference (or name) is patched:
# foo.py from collections import defaultdict def bar(): return defaultdict() # foo_test.py from mock import patch from foo import bar with patch('foo.defaultdict'): print bar()
The point here is that patch wants the full path to the thing it is patching. This just looks a little weird when patching something in the current module, since folks don't often use __main__
(or have to refer to the current module, for that matter).
patch
works by patching names. You can't achieve anything by patching the name collections.defaultdict
if you are using the name defaultdict
(in the local namespace) to access the object. See the documentation at https://docs.python.org/3/library/unittest.mock.html#where-to-patch
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