ahkam
ahkam

Reputation: 767

How to mock a custom exception in python3?

I'm doing some unit test works in python using unittest module. When i try to unittest for the custom exception, it seems like it's not working. Below is my code

# src.py
from exceptions import ClusterException, IndexingException
from utils import create_index, index_to_es
def method(bucket, key, file):
    try:
       s3_obj = get_object(bucket, key)
       ....
       ....
       create_index(index_name, index_mapping)
       index_to_es(df)
    except ClusterException as e:
       raise ClusterException(e)
    except Exception:
       raise IndexingException(e)

Here i need to test for the ClusterException exception block. So i'm mocking create_index() method to raise a ClusterException error. My testing code is

# test_src.py
with mock.patch('src.ClusterException') as mocked_cluster_exception:
     mocked_cluster_exception.side_effect = ClusterException("Bad Cluster Error")
     with mock.patch('src.create_index') as mocked_create_index:
          mocked_create_index.side_effect = ClusterException("Index creation error")
              self.assertRaises(ClusterException, method, 'bucket', 'key', 'file')

And my exception file is

# exceptions.py
class ClusterException(Exception):
    pass
class IndexingException(Exception):
    pass

But when i run this the testing is getting failed with below message. What am i missing here?

TypeError: catching classes that do not inherit from BaseException is not allowed

Upvotes: 1

Views: 2012

Answers (1)

Lin Du
Lin Du

Reputation: 102597

You don't need to patch the src.ClusterException. You should patch the create_index() function to raise a ClusterException.

E.g.

src.py:

from exceptions import ClusterException, IndexingException
from utils import create_index


def method(bucket, key, file):
    try:
        index_name = 'index_name'
        index_mapping = 'index_mapping'
        create_index(index_name, index_mapping)
    except ClusterException as e:
        print(e)
        raise ClusterException(e)
    except Exception as e:
        raise IndexingException(e)

utils.py:

def create_index(name, map):
    pass

exceptions.py:

class ClusterException(Exception):
    pass


class IndexingException(Exception):
    pass

test_src.py:

from unittest import mock, main, TestCase
from exceptions import ClusterException
from src import method


class TestSrc(TestCase):
    def test_method_to_raise_cluster_exception(self):
        with mock.patch('src.create_index') as mocked_create_index:
            mocked_create_index.side_effect = ClusterException("Index creation error")
            self.assertRaises(ClusterException, method, 'bucket', 'key', 'file')
            mocked_create_index.assert_called_once_with('index_name', 'index_mapping')


if __name__ == '__main__':
    main()

unit test result:

Index creation error
.
----------------------------------------------------------------------
Ran 1 test in 0.001s

OK
Name                                       Stmts   Miss  Cover   Missing
------------------------------------------------------------------------
src/stackoverflow/68203609/exceptions.py       4      0   100%
src/stackoverflow/68203609/src.py             12      2    83%   13-14
src/stackoverflow/68203609/test_src.py        11      0   100%
src/stackoverflow/68203609/utils.py            2      1    50%   2
------------------------------------------------------------------------
TOTAL                                         29      3    90%

Upvotes: 2

Related Questions