Как пропатчить ключевое слово повышение (или возврат) Python для модульного тестирования?

Какое пространство имен для ключевых слов Python способно отлавливать mock.patch?

Когда кто-то хочет открыть патч или распечатать mock.patch("builtins.open") или же mock.patch("mymodule.open") можно использовать, но это не работает, например, с raise,

Если бы у меня был raise somemodule.SomeException Тогда я мог бы легко проверить, было ли вызвано исключение, но как я могу утверждать, что на самом деле было вызвано ключевое слово. Нравится (с помощью pytest а также pytest-mock):

def test_myfunction_calls_raise(self, mocker):
    mocked = mocker.patch("mymodule.raise")
    mymodule.myfunction()
    mocked.assert_called_once()

РЕДАКТИРОВАТЬ: У меня есть очень хороший ответ, и поэтому mock.patch не применимо. Помимо этого и помимо очевидного решения - проверки результата - есть ли еще какой-то значимый метод проверки ключевого слова Python (raise, return,...) был вызван в коде?

РЕДАКТИРОВАТЬ 2: Фактический код, который я хочу проверить (остановка Listener pynput не работает в Xfce, поэтому я должен вызвать исключение, чтобы остановить поток слушателя):

import pynput
# ...

def stop(self):
    """Stops listener by raising an exception."""
    try:
        raise pynput.mouse.Listener.StopException
    except pynput.mouse.Listener.StopException:
        return False

РЕДАКТИРОВАТЬ 3: Метод сверху проверяется с помощью следующих двух методов испытаний:

def test_stop_stops_listener(self, mocker):
    """StopException is raised if MagicMock has got StopException attribute."""
    mocked = mocker.patch("pynput.mouse.Listener")
    with pytest.raises(TypeError):  # catching classes that do not inherit from BaseException is not allowed
        base.BaseMouse().stop()
    assert hasattr(mocked, "StopException")

def test_stop_returns_False(self, mocker):
    assert base.BaseMouse().stop() is False

1 ответ

Решение

Вы не можете исправлять ключевые слова. Они являются частью синтаксиса Python. Когда интерпретатор Python берет часть кода Python, он анализирует его и за несколько шагов преобразует в некоторое внутреннее представление ("байт-код"). Байт-код, однако, больше не имеет прямого отношения к исходному исходному коду - ключевые слова "исчезли".

Напротив, атрибуты модуля и класса, а также их доступ из кода будут по-прежнему находиться в байт-коде. Исправление является в основном временной заменой таких атрибутов.

Или, иначе говоря, вы можете исправлять атрибуты, но ключевые слова не являются атрибутами.

Другие вопросы по тегам