Python 2.7.1, mock 1.0.1
I want to write a unit test that makes use of the functionality shown here, namely successfully raising an IndexError when an attempt is made to access a mock property with subscript syntax like so:
repo = MagicMock()
repo.heads = PropertyMock(side_effect=IndexError())
with self.assertRaises(IndexError):
_ = repo.heads['nonexistant']
What is most pythonic way to do this? The code above doesn't raise an IndexError at all, but rather a TypeError indicating that PropertyMock is not subscriptable.
TypeError: 'PropertyMock' object is not subscriptable
I should note that the actual unit test doesn't look like this at all. The real unit test is attempting to assert certain behavior but cannot do so without mocking a class in the underlying third-party module, effectively replicating that underlying module's behavior when getitem is called on its Repo object which results in an IndexError being raised.
The context aside, am I being redundant by declaring repo as a MagicMock() object and then repo.heads as a PropertyMock object? I toiled over the mock documentation for awhile but there are no examples of this specific use case and I can't get this to work. I also tried using MagicMock(side_effect=IndexError()), to no avail.
It seems to me that one should be able to simply and easily facilitate this behavior in a mock and get on with their day. I trust this is possible but that I don't know how, which is why I'm asking this question.
What is the real solution?
You can use MagicMock
instead of PropertyMock
for repo.heads
. It should work for your example but I don't know if your actual tests depend on PropertyMock
.
repo = MagicMock()
repo.heads.__getitem__.side_effect = IndexError
with self.assertRaises(IndexError):
_ = repo.heads['nonexistant']
If you want it to raise IndexError
on access to particular values you should assign a custom handler function to repo.heads.__getitem__.side_effect
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With