首页 > 解决方案 > 如何模拟`subprocess.check_output`?

问题描述

我正在尝试模拟subprocess.check_output一些测试,但它似乎不起作用。考虑这段代码:

from unittest.mock import patch
from subprocess import check_output

@patch('subprocess.check_output', return_value="not a date")
def test_mock_check_output(mock_check_output):
    result = check_output(['date'])
    print(result)  # should be "not a date", but is actually the system time
    mock_check_output.assert_called() # fails!

我希望该check_output测试中的调用会转到 mock 而不是 real check_output,但它似乎会转到真实的:

% pytest -s test_mock_check_output.py
============================= test session starts ==============================
platform darwin -- Python 3.8.9, pytest-6.2.4, py-1.10.0, pluggy-0.13.1
rootdir: /Users/eaftan/test
plugins: mock-3.6.1, mock-server-0.1.0
collected 1 item                                                               

test_mock_check_output.py b'Thu Aug 19 16:51:16 PDT 2021\n'
F

=================================== FAILURES ===================================
____________________________ test_mock_check_output ____________________________

__wrapped_mock_method__ = <function NonCallableMock.assert_called at 0x105015ee0>
args = (<MagicMock name='check_output' id='4386427232'>,), kwargs = {}
__tracebackhide__ = True, msg = "Expected 'check_output' to have been called."
__mock_self = <MagicMock name='check_output' id='4386427232'>

    def assert_wrapper(
        __wrapped_mock_method__: Callable[..., Any], *args: Any, **kwargs: Any
    ) -> None:
        __tracebackhide__ = True
        try:
>           __wrapped_mock_method__(*args, **kwargs)

../.pyenv/versions/3.8.9/lib/python3.8/site-packages/pytest_mock/plugin.py:414: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <MagicMock name='check_output' id='4386427232'>

    def assert_called(self):
        """assert that the mock was called at least once
        """
        if self.call_count == 0:
            msg = ("Expected '%s' to have been called." %
                   (self._mock_name or 'mock'))
>           raise AssertionError(msg)
E           AssertionError: Expected 'check_output' to have been called.

../.pyenv/versions/3.8.9/lib/python3.8/unittest/mock.py:882: AssertionError

During handling of the above exception, another exception occurred:

mock_check_output = <MagicMock name='check_output' id='4386427232'>

    @patch('subprocess.check_output', return_value="not a date")
    def test_mock_check_output(mock_check_output):
        result = check_output(['date'])
        print(result)  # should be "not a date", but is actually the system time
>       mock_check_output.assert_called() # fails!
E       AssertionError: Expected 'check_output' to have been called.

test_mock_check_output.py:12: AssertionError
=========================== short test summary info ============================
FAILED test_mock_check_output.py::test_mock_check_output - AssertionError: Ex...
============================== 1 failed in 0.17s ===============================

注意行中的日期输出test_mock_check_output.py b'Thu Aug 19 16:51:16 PDT 2021\n',当然还有断言失败。我究竟做错了什么?

标签: pythonsubprocesspytestpython-unittest.mock

解决方案


推荐阅读