繁体   English   中英

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

[英]How to patch Python's raise (or return) keyword for the purpose of unit testing?

mock.patch能够捕获的Python关键字的命名空间是什么?

当有人想打补丁打开或打印时,可以使用mock.patch("mymodule.open") 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()

编辑:我有一个很好的答案 ,所以模拟。补丁不适用。 除此之外,除了显而易见的解决方案(测试结果)之外,还有其他有意义的技术可以测试代码中是否已调用Python关键字( raisereturn ,...)?

编辑2:我要测试的实际代码(pynput的Listener stop()在Xfce中无法正常工作,因此我必须引发异常以停止Listener线程):

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

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

相反,模块和类属性以及它们在代码中的访问仍将在字节码中找到。 修补基本上是此类属性的临时替换。

或者换句话说,您可以修补属性,但关键字不是属性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM