1

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
Lin Du
  • 88,126
  • 95
  • 281
  • 483
ahkam
  • 607
  • 7
  • 24

1 Answers1

2

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%
Lin Du
  • 88,126
  • 95
  • 281
  • 483
  • Your code is working. But my test case failing and it raises IndexingException instead of ClusterException. – ahkam Jul 01 '21 at 06:16
  • .... except ClusterException as e: raise ClusterException(e) from None except Exception as e: > raise IndexingException(e) from None E common.exceptions.IndexingException: Error: s3 to json convertion error – ahkam Jul 01 '21 at 06:20
  • but in my testcase instead of ClusterException, if i put self.assertRaises(Exception, method, 'bucket', 'key', 'file'), it's passing – ahkam Jul 01 '21 at 06:24
  • @ahkam Your code `mocked_create_index.side_effect = ClusterException("Index creation error")` raise `ClusterException` for `create_index`. If you want to raise `IndexingException`, just replace with it. – Lin Du Jul 01 '21 at 06:45
  • is there a way to share my original code with you? So that u can identify exact error – ahkam Jul 01 '21 at 06:50