Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 377
John C Avatar asked Dec 12 '13 15:12

John C


People also ask

How do you mock an exception to raise in Python?

Raising exceptions with mocks A useful attribute is side_effect . If you set this to an exception class or instance then the exception will be raised when the mock is called. >>> mock = Mock(side_effect=Exception('Boom!

How do you raise an exception in mock?

Just assign the exception to side_effect instead: mockedObj. raiseError. side_effect = Exception("Test") . You don't have to no: and his edit has a third way of doing it where he is making a Mock with the side effect set, but its still a valid, and good thing to know how to do in testing.

What is Side_effect in mock Python?

side_effect: A function to be called whenever the Mock is called. See the side_effect attribute. Useful for raising exceptions or dynamically changing return values. The function is called with the same arguments as the mock, and unless it returns DEFAULT , the return value of this function is used as the return value.

When should you not use a mock?

Only use a mock (or test double) “when testing things that cross the dependency inversion boundaries of the system” (per Bob Martin). If I truly need a test double, I go to the highest level in the class hierarchy diagram above that will get the job done. In other words, don't use a mock if a spy will do.


1 Answers

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'
like image 156
falsetru Avatar answered Sep 25 '22 18:09

falsetru