为了单元测试,如何修补Python的raise(或return)关键字?

2024-05-17 02:54:35 发布

您现在位置:Python中文网/ 问答频道 /正文

Python关键字的名称空间是什么模拟补丁你能抓住吗?你知道吗

当有人想修补打开或打印时,可以使用mock.patch("builtins.open")mock.patch("mymodule.open"),但这并不适用于raise。你知道吗

如果我有raise somemodule.SomeException语句,那么我可以很容易地测试是否引发了异常,但是如何断言实际调用了raise关键字。比如(在pytestpytest-mock的帮助下):

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

编辑:我有a very nice answer等等模拟补丁不适用。除此之外,除了显而易见的解决方案-测试结果-是否有其他有意义的技术来测试Python关键字(raisereturn,…)是否在代码中被调用?你知道吗

编辑2: 我想要测试的实际代码(pynput的Listener stop()在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

Tags: testselfpytestdef关键字mockpatchraise
1条回答
网友
1楼 · 发布于 2024-05-17 02:54:35

你不能修补关键字。它们是Python语法的一部分。当Python解释器获取一段Python代码时,它会对其进行解析,并分几个步骤将其转换为某种内部表示形式(“字节码”)。然而,字节码与原始源代码不再有直接关系——关键字已经“消失”。你知道吗

相反,模块和类属性以及它们在代码中的访问仍然可以在字节码中找到。修补基本上是临时替换这些属性。你知道吗

或者,换言之,可以修补属性,但关键字不是属性。你知道吗

相关问题 更多 >