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

fen*_*eer 5 python mocking

Python 2.7.1,模拟1.0.1

我想编写一个使用此处所示功能的单元测试,即在尝试使用下标语法访问mock属性时成功引发IndexError,如下所示:

repo = MagicMock()
repo.heads = PropertyMock(side_effect=IndexError())
with self.assertRaises(IndexError):
    _ = repo.heads['nonexistant']
Run Code Online (Sandbox Code Playgroud)

什么是最pythonic的方式来做到这一点?上面的代码根本不会引发IndexError,而是引发TypeMock不可订阅的TypeError.

TypeError:'PropertyMock'对象不可订阅

我应该注意到,实际的单元测试看起来并不像这样.真正的单元测试试图断言某些行为,但是如果没有在底层第三方模块中模拟一个类就不能这样做,当在其Repo对象上调用getitem时会有效地复制底层模块的行为,从而导致引发IndexError.

除了上下文之外,通过将repo声明为MagicMock()对象然后repo.heads作为PropertyMock对象,我是多余的吗?我在模拟文档上工作了一段时间,但没有这个特定用例的例子,我无法让它工作.我也尝试过使用MagicMock(side_effect = IndexError()),但无济于事.

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

什么是真正的解决方案?

and*_*and 5

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

repo = MagicMock()
repo.heads.__getitem__.side_effect = IndexError
with self.assertRaises(IndexError):
    _ = repo.heads['nonexistant']
Run Code Online (Sandbox Code Playgroud)

如果您希望它IndexError在访问特定值时引发,则应为其分配自定义处理函数repo.heads.__getitem__.side_effect.