Python: Mock ImportError с pytest.fixture - PullRequest
       18

Python: Mock ImportError с pytest.fixture

0 голосов
/ 30 октября 2019

Я пытаюсь создать тесты для вспомогательной функции, которая реагирует на успешное импортирование или нет.

Успешный тест работает, но не на неудачный, знаете, почему?

Помощник: домашний помощник / компоненты / owntracks / helper.py

"""Helper for OwnTracks."""
try:
    import nacl
except ImportError:
    nacl = None

import logging

_LOGGER = logging.getLogger(__name__)


def supports_encryption() -> bool:
    """Test if we support encryption."""
    _LOGGER.info(nacl)
    return nacl is not None

Мой тест: тесты / компоненты / owntracks / test_helper.py

"""Test the owntracks helper."""
from unittest.mock import patch
import pytest
import logging

from homeassistant.components.owntracks.helper import supports_encryption

_LOGGER = logging.getLogger(__name__)

@pytest.fixture(name="nacl_imported")
def mock_nacl_imported():
    """Mock a successful import."""
    with patch("homeassistant.components.owntracks.helper.nacl"):
        yield


@pytest.fixture(name="nacl_not_imported")
def mock_nacl_not_imported():
    """Mock non successful import."""
    with patch("homeassistant.components.owntracks.helper.nacl") as mock_import:
        mock_import.return_value = ImportError()
        yield mock_import


def test_supports_encryption(nacl_imported):
    """Test if env supports encryption."""
    _LOGGER.info(supports_encryption())
    assert supports_encryption()


def test_supports_encryption_failed(nacl_not_imported):
    """Test if env does not support encryption."""
    _LOGGER.info(supports_encryption())
    assert not supports_encryption()

Также попытался:

    with patch("homeassistant.components.owntracks.helper.nacl", return_value=None):
        yield

AND

    with patch("homeassistant.components.owntracks.helper.nacl", side_effect=ImportError()):
        yield

Журналы испытаний:

 py.test tests/components/owntracks/test_helper.py
Test session starts (platform: linux, Python 3.7.4, pytest 5.2.2, pytest-sugar 0.9.2)
rootdir: /home/quentin.pollet@sglk.local/Documents/home-assistant, inifile: setup.cfg
plugins: timeout-1.3.3, cov-2.8.1, requests-mock-1.7.0, aiohttp-0.3.0, sugar-0.9.2
collecting ... 
 tests/components/owntracks/test_helper.py ✓                                       50% █████     

―――――――――――――――――――――――――――――――― test_supports_encryption_failed ――――――――――――――――――――――――――――――――

nacl_not_imported = <MagicMock name='nacl' id='139733318227280'>

    def test_supports_encryption_failed(nacl_not_imported):
        """Test if env does not support encryption."""
        _LOGGER.info(supports_encryption())
>       assert not supports_encryption()
E       assert not True
E        +  where True = supports_encryption()

tests/components/owntracks/test_helper.py:34: AssertionError
------------------------------------- Captured stderr call --------------------------------------
INFO:homeassistant.components.owntracks.helper:<MagicMock name='nacl' id='139733318227280'>
INFO:tests.components.owntracks.test_helper:True
INFO:homeassistant.components.owntracks.helper:<MagicMock name='nacl' id='139733318227280'>
--------------------------------------- Captured log call ---------------------------------------
INFO     homeassistant.components.owntracks.helper:helper.py:14 <MagicMock name='nacl' id='139733318227280'>
INFO     tests.components.owntracks.test_helper:test_helper.py:33 True
INFO     homeassistant.components.owntracks.helper:helper.py:14 <MagicMock name='nacl' id='139733318227280'>

 tests/components/owntracks/test_helper.py ⨯                                      100% ██████████

Results (0.15s):
       1 passed
       1 failed
         - tests/components/owntracks/test_helper.py:31 test_supports_encryption_failed

Я новичок в Python, но мотивирован, будь хорошим;)

1 Ответ

0 голосов
/ 04 ноября 2019

Исходя из ваших данных, ясно, что метод supports_encryption () проверит состояние импорта nacl. Если он не установлен, он изменит значение nacl на False. Более того, после этого вы проверяете значение nacl с помощью True / False (nacl не равен None и возвращает True, если не None).

Возвращаемое значение supports_encryption () всегда будет True.

В тестовом методе test_supports_encryption_failed () вы использовали assert not supports_encryption (), поэтому он не работает.

ДляПодчеркивая стоимость импорта, используйте ниже: -

$ pytest -vsx test_11.py
platform linux2 -- Python 2.7.15+, pytest-4.6.6, py-1.8.0, pluggy-0.13.0 -- /usr/bin/python
cachedir: .pytest_cache
metadata: {'Python': '2.7.15+', 'Platform': 'Linux-4.15.0-60-generic-x86_64-with-Ubuntu-18.04-bionic', 'Packages': {'py': '1.8.0', 'pytest': '4.6.6', 'pluggy': '0.13.0'}, 'Plugins': {u'html': u'1.22.0', u'metadata': u'1.8.0'}}
rootdir: /home/nikhilesh
plugins: html-1.22.0, metadata-1.8.0
collected 2 items                                                                                                                                                      

test_11.py::test_success ('Value is ', <module 'os' from '/usr/lib/python2.7/os.pyc'>)
PASSED
test_11.py::test_fail ('Value is ', None)
PASSED

======================================================================= 2 passed in 0.07 seconds =======================================================================
$ cat test_11.py 
import utility
import mock



def test_success():
    print("Value is ", utility.os)



@mock.patch("utility.os", return_value = None)
def test_fail(mock_os):
    print("Value is ", utility.os.return_value)
...