简体   繁体   中英

Mock relative import from same python module

Given the following package structure:

# tree
.
├── setup.py
└── src
    └── package
        ├── bar.py
        ├── __init__.py
        └── test.py

And the following code:

# bar.py
from glob import glob

def baz():
    return glob('./*')

How can I correctly mock the call to glob in bar.baz when performing a relative import in test.py ? I've tried several approaches, including

# test.py
from unittest import mock
from .bar import baz

@mock.patch('package.bar.baz')
def test_baz(mock_baz):
    mock_baz.return_value = ['fizz']
    assert "fizz" in baz()


# pytest src/package/test.py
============================= test session starts ==============================
platform linux -- Python 3.7.1, pytest-4.0.0, py-1.7.0, pluggy-0.8.0
rootdir: /home/bewing/package, inifile:
plugins: cov-2.6.0, pylama-7.6.6, celery-4.2.1
collected 1 item

src/package/test.py F                                                    [100%]

=================================== FAILURES ===================================
___________________________________ test_baz ___________________________________

mock_baz = <MagicMock name='baz' id='140447846207104'>

    @mock.patch('package.bar.baz')
    def test_baz(mock_baz):
        mock_baz.return_value = ['fizz']
>       assert "fizz" in baz()
E       AssertionError: assert 'fizz' in ['./setup.py', './src']
E        +  where ['./setup.py', './src'] = baz()

src/package/test.py:7: AssertionError
=========================== 1 failed in 0.33 seconds ===========================

and

# test.py
from unittest import mock
from .bar import baz

    @mock.patch('.bar.baz')
    def test_baz(mock_baz):
        mock_baz.return_value = ['fizz']
        assert "fizz" in baz()

# pytest src/package/test.py
============================= test session starts ==============================
platform linux -- Python 3.7.1, pytest-4.0.0, py-1.7.0, pluggy-0.8.0
rootdir: /home/bewing/package, inifile:
plugins: cov-2.6.0, pylama-7.6.6, celery-4.2.1
collected 1 item

src/package/test.py F                                                    [100%]

=================================== FAILURES ===================================
___________________________________ test_baz ___________________________________

args = (), keywargs = {}, extra_args = [], entered_patchers = []
exc_info = (<class 'ValueError'>, ValueError('Empty module name'), <traceback object at 0x7effb803a4c8>)
patching = <unittest.mock._patch object at 0x7effbab69a58>

    @wraps(func)
    def patched(*args, **keywargs):
        extra_args = []
        entered_patchers = []

        exc_info = tuple()
        try:
            for patching in patched.patchings:
>               arg = patching.__enter__()

/home/bewing/.pyenv/versions/3.7.1/lib/python3.7/unittest/mock.py:1183:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/home/bewing/.pyenv/versions/3.7.1/lib/python3.7/unittest/mock.py:1239: in __enter__
    self.target = self.getter()
/home/bewing/.pyenv/versions/3.7.1/lib/python3.7/unittest/mock.py:1409: in <lambda>
    getter = lambda: _importer(target)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

target = '.bar'

    def _importer(target):
        components = target.split('.')
        import_path = components.pop(0)
>       thing = __import__(import_path)
E       ValueError: Empty module name

/home/bewing/.pyenv/versions/3.7.1/lib/python3.7/unittest/mock.py:1092: ValueError
=========================== 1 failed in 0.47 seconds ===========================

You should patch glob not baz . Something like:

@mock.patch('package.bar.glob')
def test_baz(mock_glob):
    mock_glob.return_value = ['fizz']
    assert "fizz" in baz()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM