使用 Pytest 在函数中模拟引发异常

A S*_*mer 2 python postgresql exception mocking pytest

我有以下功能get_postgres_connection。我正在尝试运行单元测试来test_get_postgres_connection_unsuccess命中异常。

\n
def get_postgres_connection():\n        \n        try:\n            conn = psycopg2.connect(dbname = POSTGRES_DATABASE,\n                                user = POSTGRES_USER,\n                                password = POSGRES_PASSWORD,\n                                host = POSTGRES_HOST,\n                                port =\xc2\xa0POSTGRES_PORT)\n            conn.autocommit = True\n            \n            return conn\n            \n        except Exception as err:\n            logging.error(\'Unable to connect to postgres db: %s\', err)\n\n\ndef test_get_postgres_connection_unsuccess(monkeypatch):\n        """ tests an exception is hit if the connection to postgres is unsuccesful"""\n        \n        # setup\n        class mock_conn:\n            def __init__(self, dbname, user, password, host, port):\n                raise ConnectionError(\'This fake connection did not work\')\n\n            autocommit = False\n\n        monkeypatch.setattr(psycopg2, \'connect\', mock_conn)\n
Run Code Online (Sandbox Code Playgroud)\n

我无法在模拟函数中成功引发异常。有人知道我在这里做错了什么吗?

\n

编辑:稍微清理一下代码

\n

jfa*_*oni 5

无需创建您自己的模拟类 -unittest.mock.MagicMock而是使用。

您可以使用MagicMock实例来模拟任何东西,包括第三方函数。如果添加side_effect=Exception()参数,则调用模拟时会引发异常。

Python 甚至允许您在上下文管理器(语句)中执行此操作with ...,以便一旦上下文管理器块结束,模拟函数就会“取消模拟”。

最小的例子:

def some_external_lib():  # this is psycopg2.connect in your example
    pass

def my_func():  # this is get_postgres_connection in your example
    try:
        some_external_lib()
    except Exception as e:
        print(f"Error found: {e}")


import unittest
from unittest import mock

class TestMyFunc(unittest.TestCase):
    def test_my_func_external_lib_raises_exception(self):
        with mock.patch('__main__.some_external_lib', side_effect=Exception("ERROR")):
            my_func()


# Running example - prints the error message
t = TestMyFunc()
t.test_my_func_external_lib_raises_exception()
Run Code Online (Sandbox Code Playgroud)

请注意,正如所编写的那样,测试现在实际上并没有测试任何内容。查看函数的主体get_postgres_connection,您可能想测试它是否返回None,以及在外部库引发异常的情况下是否将某些内容写入日志文件。