Reputation: 5462
A while back I found the following solution-pattern here on StackOverflow for raising an error from a mocked function (I cannot find the original link anymore, sorry):
def _mock_raises_error(my_mock, error_type, output):
my_mock.return_value = mock.Mock()
my_mock.side_effect = error_type(output)
# for example
with mock.patch('mymodule.interface.function') as mock_function:
_mock_raises_error(mock_function, Exception, 'Some error-message')
This works as intended, so I always have used this pattern.
Recently a colleague of mine asked why this definition both has a return_value
as a side_effect
and why that was needed. And to my shame I could not come up with the correct answer (only that I copied it from StackOverflow, but that is not an explanation why it is correct).
So now my question (to be able to explain it in the future) is why isn't giving the side_effect
enough? What does the return_value
add?
Upvotes: 2
Views: 3837
Reputation: 12329
Let's start with the documentation for unittest.mock.
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.
Alternatively side_effect can be an exception class or instance. In this case the exception will be raised when the mock is called.
return_value: The value returned when the mock is called. By default this is a new Mock (created on first access). See the return_value attribute.
One generally tests either with a return_value or with a side_effect. In my experience, I often test with return_value. This is for my standard case, when I'm trying to mock some functionality (such as obtaining the contents of a directory) without the need to make a function call (such as to the OS and to a directory which might change).
I mock the side_effect less often (usually when I'm testing the function's reaction to an exception). (Example, when I'm handling a file-not-found exception.)
In this example of a function that tests for the existence of a file in a directory, I might want to have both the results (say an empty list of files) and the side effect (say a file-not-found exception). But generally I will test one or the other.
The OP's example is only testing for the exception, so the side-effect is critical (but the return value is not). If you were testing for both, you'd need both.
Upvotes: 2