模拟在Python 2.7中访问时引发异常的可订阅属性的正确方法是什么?

模拟在Python 2.7中访问时引发异常的可订阅属性的正确方法是什么?,python,mocking,Python,Mocking,Python2.7.1,mock 1.0.1 我想编写一个单元测试,它利用了这里显示的功能,即在尝试使用下标语法访问mock属性时成功地引发索引器,如下所示: repo = MagicMock() repo.heads = PropertyMock(side_effect=IndexError()) with self.assertRaises(IndexError): _ = repo.heads['nonexistant'] 什么是最具蟒蛇式的方法?上面的代码根本不会引发索引器,而

Python2.7.1,mock 1.0.1

我想编写一个单元测试,它利用了这里显示的功能,即在尝试使用下标语法访问mock属性时成功地引发索引器,如下所示:

repo = MagicMock()
repo.heads = PropertyMock(side_effect=IndexError())
with self.assertRaises(IndexError):
    _ = repo.heads['nonexistant']
什么是最具蟒蛇式的方法?上面的代码根本不会引发索引器,而是一个类型错误,指示PropertyMock不可订阅

TypeError:“PropertyMock”对象不可下标

我应该注意到,实际的单元测试根本不像这样。真正的单元测试正在尝试断言某些行为,但如果不模拟底层第三方模块中的类,则无法这样做,从而在对其Repo对象调用getitem时有效地复制底层模块的行为,从而引发索引器

撇开上下文不谈,将repo声明为MagicMock()对象,然后将repo.heads声明为PropertyMock对象,这是多余的吗?我花了一段时间研究模拟文档,但是没有这个特定用例的例子,我无法让它工作。我还尝试使用MagicMock(side_effect=indexer()),但没有成功

在我看来,一个人应该能够简单而轻松地在模拟中促进这种行为,并继续他们的一天。我相信这是可能的,但我不知道怎么做,这就是为什么我要问这个问题


真正的解决方案是什么?

您可以使用
MagicMock
而不是
PropertyMock
进行
repo.heads
。它应该适用于您的示例,但我不知道您的实际测试是否依赖于
PropertyMock

repo = MagicMock()
repo.heads.__getitem__.side_effect = IndexError
with self.assertRaises(IndexError):
    _ = repo.heads['nonexistant']
如果您希望它在访问特定值时引发
索引器
,则应为
repo.heads.\uuu getitem\uuuuuu.side\u effect
分配一个自定义处理程序函数