Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocking - How do I raise exception on the caller?

Suppose this is the code

def move(*args, **kwargs):   
    try:
        shutil.move(source, destination)
    except Exception as e:
        raise e

and in my tests.py

@patch.object(shutil, 'move')
def test_move_catch_exception(self, mock_rmtree):
    ''' Tests moving a target hits exception. '''
    mock_rmtree.side_effect = Exception('abc')
    self.assertRaises(Exception, move,
                             self.src_f, self.src_f, **self.kwargs)

It said this

  File "unittests.py", line 84, in test_move_catch_exception
    self.src_f, self.src_f, **self.kwargs)
AssertionError: Exception not raised

If I assert on mock_rmtree it will pass. How can I assert on the caller (in this case, the function move)?


As aquavitae pointed out, the primary reasons was copy-paste error, and also I was asserting a tuple in the beginning. Always asseert with the right return type...

like image 331
CppLearner Avatar asked Apr 25 '12 03:04

CppLearner


People also ask

How do I manually raise an exception?

Throwing exceptions manually To throw an exception explicitly you need to instantiate the class of it and throw its object using the throw keyword.

How do you raise an exception in Python 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 the difference between mock and MagicMock?

With Mock you can mock magic methods but you have to define them. MagicMock has "default implementations of most of the magic methods.". If you don't need to test any magic methods, Mock is adequate and doesn't bring a lot of extraneous things into your tests.


1 Answers

You've got a typo in your example, missing a '.

Its not entirely clear what you're asking, but if I understand you correctly, you're asking how to test that a raised exception is caught inside move. One problem is that you're patching shutil.rmtree, not shutil.move, but you can't be certain thatshutil.rmtree will ever be called. shutil.move only actually calls shutil.rmtree if it successfully copies a directory, but since you're copying self.src_f to itself, this doesn't happen. This is not a very good way of patching it though, because the assumption that shutil.move will call shutil.rmtree at all is not guaranteed and is implementation dependent.

As for how to test it, simply check that the return value is as expected:

@patch.object(shutil, 'move')
def test_move_catch_exception(self, mock_move):
    ''' Tests moving a target hits exception. '''
    e = OSError('abc')
    mock_move.side_effect = e
    returns = move(self.src_f, self.src_f, **self.kwargs)
    assert returns == (False, e)
like image 113
aquavitae Avatar answered Sep 28 '22 04:09

aquavitae