如何在 python3 中模拟自定义异常?

How to mock a custom exception in python3?

我正在 python 使用 unittest 模块做一些单元测试工作。当我尝试对自定义异常进行单元测试时,它似乎不起作用。下面是我的代码

# 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)

这里我需要测试 ClusterException 异常块。所以我在模拟 create_index() 方法来引发 ClusterException 错误。我的测试代码是

# 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')

我的异常文件是

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

但是当我 运行 测试失败并显示以下消息时。我在这里错过了什么?

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

您不需要修补 src.ClusterException。您应该修补 create_index() 函数以引发 ClusterException.

例如

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()

单元测试结果:

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

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