Как смоделировать / проверить регистратор, который сообщает об исключении? - PullRequest
0 голосов
/ 26 марта 2019

Может ли кто-нибудь из вас объяснить, почему следующее assert_called_with не работает, пожалуйста?

Согласно информации, напечатанной pytest 'Ожидаемый вызов', равно 'Фактический вызов', поэтому я предполагаю, что некоторая информациятеряется, когда pytest преобразует его в str для печати на терминале.

Какой инструмент вы бы порекомендовали для его отладки?

Программа:

import logging
from mock import patch

logger = logging.getLogger(__name__)
logger.addHandler(logging.StreamHandler())

def func():
    try:
        raise ValueError("error XYZ")
    except ValueError as err:
        logger.error(err)

def test_func():
    with patch('logging.Logger.error') as log:
        func()
        log.assert_called_with(ValueError("error XYZ"))

Выполнение:

$ pytest prog.py
=========================================================================== test session starts ===========================================================================
platform linux2 -- Python 2.7.15+, pytest-4.2.0, py-1.7.0, pluggy-0.8.1
rootdir: /tmp, inifile:
collected 1 item

prog.py F                                                                                                                                                           [100%]

================================================================================ FAILURES =================================================================================
________________________________________________________________________________ test_func ________________________________________________________________________________

    def test_func():
        with patch('logging.Logger.error') as log:
            func()
>           log.assert_called_with(ValueError("error XYZ"))

prog.py:16:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/home/ebajgrz/py27/local/lib/python2.7/site-packages/mock/mock.py:937: in assert_called_with
    six.raise_from(AssertionError(_error_message(cause)), cause)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

value = AssertionError("Expected call: error(ValueError('error XYZ',))\nActual call: error(ValueError('error XYZ',))",), from_value = None

    def raise_from(value, from_value):
>       raise value
E       AssertionError: Expected call: error(ValueError('error XYZ',))
E       Actual call: error(ValueError('error XYZ',))

/home/ebajgrz/py27/local/lib/python2.7/site-packages/six.py:737: AssertionError
======================================================================== deprecated python version ========================================================================
You are using Python 2.7.15, which will no longer be supported in pytest 5.0
For more information, please read:
  https://docs.pytest.org/en/latest/py27-py34-deprecation.html
======================================================================== 1 failed in 0.28 seconds ============================

Я понимаю, что у pytest есть каплог, и тест можно реализовать следующим образом, но я хотел бы понять, почему первый метод не работает.

def test_func2(caplog):
    func()
    assert 'error XYZ' in caplog.text

1 Ответ

1 голос
/ 26 марта 2019

Это потому, что mock проверяет переданный объект на ожидаемый объект.Это разные объекты, поэтому утверждение неверно.Например, откройте оболочку Python и попробуйте следующее:

>>> ValueError('bees') == ValueError('bees')
False

Они не равны, потому что это разные объекты.Но попробуйте это:

>>> str(ValueError('bees')) == str(ValueError('bees'))
True

Это потому, что строки неизменяемы.Теперь, если вы измените свой исходный вызов журнала следующим образом: logger.error(str(err)) и измените свое утверждение на: log.assert_called_with(str(ValueError("error XYZ"))), я думаю, что вы пройдете эту первую ошибку.

Не связано с этим и т. Д.предложения для регистрации исключений: вы можете захотеть зарегистрировать больше информации в блоке исключений, подобном этому.Примерно так:

logger.error('Error raised doing something: %s', str(err), exc_info=True)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...