Python – How to use Python Mock to raise an exception – but with Errno set to a given value

mockingpythonunit testing

Given this Python code:

elif request.method == 'DELETE':
    try:
        os.remove(full_file)
        return jsonify({'results':'purged %s' % full_file})

    except OSError as e:
        if e.errno != errno.ENOENT:
            raise

        return jsonify({'results':'file not present: %s' % full_file})

I want to test all possible paths, including the exception handling. Using Mock, it's easy enough to raise an exception, which I do with this code:

with patch('os.remove', new=Mock(side_effect=OSError(errno.ENOENT))):
    self.assertRaises(OSError, self.app.delete, file_URL) # broken

Mock raises an exception, which has a printed value of 2 (ENOENT) – but e.errno is set to NONE. And so far, I have not found a way to set it. The result is, the exception always gets re-raised, and I never reach the last line of code, in my unit test.

I've also tried creating a dummy class with errno set, and returning that. But unless it has *side_effect* set to be called, it doesn't raise an exception, and when I set side_effect, I don't get the object.errno as a return value.

Is there a way to have Mock raise an Exception, where that Exception object has the errno attribute set?

Best Answer

Pass two arguments to OSError constructor. (First one should be errno).

For example:

>>> OSError(2).errno
>>> OSError(2, 'message').errno
2
>>> OSError(2, 'message').strerror
'message'