Search code examples
pythonpython-3.xmockingpython-sphinxautodoc

Mocking submodules in python


I am trying to generate autodocumentation of my project through sphinx. However, I will run the generation of the autodocs in an environment that won't have all the modules I am importing. Hence I would like to mock the import statements.

On http://read-the-docs.readthedocs.io/en/latest/faq.html I found this trick for C modules:

import sys
from unittest.mock import MagicMock

class Mock(MagicMock):
    @classmethod
    def __getattr__(cls, name):
        return Mock()

MOCK_MODULES = ['pygtk', 'gtk', 'gobject', 'argparse', 'numpy', 'pandas']
sys.modules.update((mod_name, Mock()) for mod_name in MOCK_MODULES)

However mocking getattr does not solve cases like these:

from foo.bar import blah

that is, when there is a dot [.] involved in the import statement.

Anyone any idea how to get all my imports mocked for a specific list of modules?


Solution

  • The import

    from foo.bar import blah
    

    will look for sys.modules['foo.bar']. Just insert that:

    >>> from foo.bar import blah
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ModuleNotFoundError: No module named 'foo'
    >>> import sys
    >>> from unittest import mock
    >>> sys.modules['foo.bar'] = mock.Mock()
    >>> from foo.bar import blah
    >>> blah
    <Mock name='mock.blah' id='4362289896'>