我正在使用python2.7.15rc1。我试图模拟迭代器,以便它在迭代时抛出异常。例:
elements = [1,2,3,Exception('boom!')]
iterable = <create a mock iterable to iterate over "elements">
# this does not print anything.
for value in iterable:
...我尝试在side_effect实例的next()方法上使用MagicMock属性,如下所示:
from mock import MagicMock
mocked_next = MagicMock()
mocked_next.next.side_effect = [1,2,3,Exception('boom!')]
mocked_iterable = MagicMock()
mocked_iterable.__iter__.return_value = mocked_next
...
# This does not print anything and no exception is raised
for value in mocked_iterable:
print(value)我假设for循环最终会调用mocked_iterable上的__iter__,后者返回另一个带有具有side_effect的next属性的模拟对象。我的期望是循环最终会调用mocked_next.next(),这将迭代我在side_effect中提供给它的列表。
显然,我的理解是不正确的。我在这里错过了什么?这是否可以完全通过模拟来实现,或者我是否必须创建一个自定义迭代器来实现这个行为?
编辑:,我正在尝试测试一段代码的异常处理部分,该代码在可迭代的基础上迭代,因此试图模拟一个抛出异常的迭代器。
发布于 2019-04-03 18:48:20
您要寻找的东西不适合MagicMock,因为side_effect可以是异常,也可以是可迭代的,但不能两者兼而有之。相反,您应该创建一个具有__iter__方法的类,该方法生成给定序列中的项,然后引发给定的异常:
class ExceptionRaisingIterable:
def __init__(self, seq, exception):
self.seq = seq
self.exception = exception
def __iter__(self):
for i in self.seq:
yield i
raise self.exception
for value in ExceptionRaisingIterable([1, 2, 3], Exception('boom!')):
print(value)这一产出如下:
1
2
3
Traceback (most recent call last):
File "test.py", line 11, in <module>
for value in ExceptionRaisingIterable([1, 2, 3], Exception('boom!')):
File "test.py", line 9, in __iter__
raise self.exception
Exception: boom!https://stackoverflow.com/questions/55501898
复制相似问题