[英]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关键字。 像(在pytest
和pytest-mock
的帮助下):
def test_myfunction_calls_raise(self, mocker):
mocked = mocker.patch("mymodule.raise")
mymodule.myfunction()
mocked.assert_called_once()
编辑:我有一个很好的答案 ,所以模拟。补丁不适用。 除此之外,除了显而易见的解决方案(测试结果)之外,还有其他有意义的技术可以测试代码中是否已调用Python关键字( raise
, return
,...)?
编辑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.