第一次调用后抛出异常
Throw exception after first call
我有一个循环,用于将记录添加到 zip 文件。我模拟了我的 zipfile 对象,我想抛出一个异常来验证我处理大型 zipfile 的逻辑是否能正常工作。
有没有办法使用 MagicMocks 或普通模拟来接受第一个调用,但在第二个调用时引发异常?
使用生成器和 Mock side_effect
from unittest.mock import Mock
def sample_generator():
yield 1
yield 2
raise Exception()
gen = sample_generator()
def sideeffect():
global gen
for x in gen:
return x
m = Mock(side_effect=sideeffect)
m() #1
m() #2
m() #3
您可以获得:
File "test.py", line 22, in <module>
m() #3
....
raise Exception()
Exception
我相信你可以通过一些努力让它变得更干净一些,但它应该可以解决你的基本问题
最简单的方法是使用 side_effect
接受可迭代、可调用或异常(class 或实例)
Alternatively side_effect
can be an exception class or instance. In this case the exception will be raised when the mock is called.
如 Quick Guide 所示,您可以使用 side_effect
简单地通过
引发异常
>>> mock = Mock(side_effect=KeyError('foo'))
>>> mock()
Traceback (most recent call last):
...
KeyError: 'foo'
此外,您可以在 side_effect
赋值中一起使用 list 和 Exception。所以做你需要的最简单的方法是这样的:
>>> m = Mock(side_effect=[1, KeyError("bar"), 3])
>>> m("a")
1
>>> m("b")
...
KeyError: 'bar'
>>> m("c")
3
另一种方法是使用可调用对象来编写模拟应如何反应的逻辑。在这种情况下,您可以根据参数或测试状态自由选择。
我有一个循环,用于将记录添加到 zip 文件。我模拟了我的 zipfile 对象,我想抛出一个异常来验证我处理大型 zipfile 的逻辑是否能正常工作。
有没有办法使用 MagicMocks 或普通模拟来接受第一个调用,但在第二个调用时引发异常?
使用生成器和 Mock side_effect
from unittest.mock import Mock
def sample_generator():
yield 1
yield 2
raise Exception()
gen = sample_generator()
def sideeffect():
global gen
for x in gen:
return x
m = Mock(side_effect=sideeffect)
m() #1
m() #2
m() #3
您可以获得:
File "test.py", line 22, in <module>
m() #3
....
raise Exception()
Exception
我相信你可以通过一些努力让它变得更干净一些,但它应该可以解决你的基本问题
最简单的方法是使用 side_effect
接受可迭代、可调用或异常(class 或实例)
Alternatively
side_effect
can be an exception class or instance. In this case the exception will be raised when the mock is called.
如 Quick Guide 所示,您可以使用 side_effect
简单地通过
>>> mock = Mock(side_effect=KeyError('foo')) >>> mock() Traceback (most recent call last): ... KeyError: 'foo'
此外,您可以在 side_effect
赋值中一起使用 list 和 Exception。所以做你需要的最简单的方法是这样的:
>>> m = Mock(side_effect=[1, KeyError("bar"), 3])
>>> m("a")
1
>>> m("b")
...
KeyError: 'bar'
>>> m("c")
3
另一种方法是使用可调用对象来编写模拟应如何反应的逻辑。在这种情况下,您可以根据参数或测试状态自由选择。