Python:使用pytest.fixture模拟ImportError

时间:2019-10-30 16:45:37

标签: python-3.x patch python-mock

我正在尝试对是否对导入成功有反应的辅助函数进行测试。

成功测试有效,但失败了,你知道为什么吗?

助手: homeassistant / components / 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 :(得分:0)

根据您提供的详细信息,很显然方法 supports_encryption ()将检查nacl的导入状态。如果未安装,则会将 nacl 值更改为False。此外,在此之后,您要使用True / False验证nacl的值(如果nacl不是None,则返回True,如果不是,则返回True)。

supports_encryption ()的返回值始终为True。

在测试方法test_supports_encryption_failed()中,您使用了断言而不是 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)