How can I make mock.mock_open raise an IOError?

mocking, python, unit-testing

Solution

Assign the exception to `mock.mock_open.side_effect`:

mock.mock_open.side_effect = IOError

From the `mock.Mock.side_effect` documentation:

This can either be a function to be called when the mock is called, or an exception (class or instance) to be raised.

Demo:

>>> mock = MagicMock()
>>> mock.mock_open.side_effect = IOError()
>>> mock.mock_open()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/mj/Development/venvs/stackoverflow-2.7/lib/python2.7/site-packages/mock.py", line 955, in __call__
    return _mock_self._mock_call(*args, **kwargs)
  File "/Users/mj/Development/venvs/stackoverflow-2.7/lib/python2.7/site-packages/mock.py", line 1010, in _mock_call
    raise effect
IOError

When using `patch()` as a context manager, a new mock object is produced; assign to that mock object:

with mock.patch('__main__.open', mo, create=True) as mocked_open:
    mocked_open.side_effect = IOError()
    self.controller.loadPrivkey()

Problem

I need to test a instance method that calls `open`. In the first test case, I set `mock.mock_open` to return a string, as expected. This works wonderfully. However, I also need to test the case in which an `IOError` is thrown from this function. How can I make `mock.mock_open` raise an arbitrary exception? This is my approach so far: ``` @mock.patch.object(somemodule, 'generateDefaultKey') def test_load_privatekey(self, genkey) mo = mock.mock_open(read_data=self.key) mo.side_effect = IOError with mock.patch('__main__.open', mo, create=True): self.controller.loadPrivkey() self.assertTrue(genkey.called, 'Key failed to regenerate') ```

Original source