使用Try和Except时如何在Python中对错误进行单元测试

使用Try和Except时如何在Python中对错误进行单元测试,python,python-3.x,unit-testing,mocking,monkeypatching,Python,Python 3.x,Unit Testing,Mocking,Monkeypatching,我正在尝试对我的一个函数进行单元测试,以确保数据库连接有效,如果无效,则引发适当的异常。鉴于数据库连接无效,我很难测试是否引发了适当的异常 我已经成功模拟了数据库连接,并在连接有效时获得了想要的结果。然而,尽管测试成功,但它肯定没有按预期工作。当我用一个特定的错误模拟数据库连接并断言引发了不同的错误时,测试仍然通过,即使它们是不同的错误。有关更多详细信息,请参见代码 def get_database(): try: conn = pyodbc.connect(

我正在尝试对我的一个函数进行单元测试,以确保数据库连接有效,如果无效,则引发适当的异常。鉴于数据库连接无效,我很难测试是否引发了适当的异常

我已经成功模拟了数据库连接,并在连接有效时获得了想要的结果。然而,尽管测试成功,但它肯定没有按预期工作。当我用一个特定的错误模拟数据库连接并断言引发了不同的错误时,测试仍然通过,即使它们是不同的错误。有关更多详细信息,请参见代码

def get_database():
    try:
        conn = pyodbc.connect(
            r'Driver={Microsoft Access Driver (*.mdb, *.accdb)};'
            r'DBQ=M:\Path\To\Database\My_Database.accdb;'
        )
        return conn
    # I want to assert this specific error is raised given bad connection
    except pyodbc.Error as err: 
        raise err

@mock.patch('directory1.script1.pyodbc.connect')
def test_database_connection_error(self, mock_conn):

        # If connection is valid test works as intended!
        get_database()
        mock_conn.assert_called_once_with((
            r'Driver={Microsoft Access Driver (*.mdb, *.accdb)};'
            r'DBQ=M:\Path\To\Database\My_Database.accdb;'
        ))

        # This test still passes even though the errors are different!
        mock_conn.side_effect = pyodbc.ProgrammingError
        self.assertRaises(pyodbc.Error, get_database)

我预计,如果模拟数据库连接设置为一种类型的错误,并且断言了另一种错误,那么测试应该失败。事实并非如此。

pyodbc.ProgrammingError
pyodbc.DatabaseError
的一个子类,它是
pyodbc.Error
的一个子类,因此您的:

self.assertRaises(pyodbc.Error, get_database)
只要引发
pyodbc.Error
子类的任何异常实例,包括
pyodbc.DatabaseError
,它就会通过


您应该明确您想要捕获的是
pyodbc.Error
的哪个子类。

非常感谢!我想你可能熟悉pyodbc?我希望捕获的错误是数据库路径不存在时(即数据库被删除、移动等)。当我以错误的路径运行函数时,我会得到一个冗长的回溯,这真的没有帮助。它太长了,我甚至不能把它贴在这里,但它的开头是:pyodbc。错误:('HY000',“[HY000][Microsoft][ODBC-Microsoft-Access-Driver]一般错误无法打开注册表项临时(volatile)进程0x2078线程0x3f24 DBC 0xa2680b4的Ace DSN。不确定我在寻找哪个子类…很高兴能提供帮助。不幸的是,我不知道您在这里描述的具体错误。您最好将此问题作为带有适当标记的新问题发布,以便更多具有正确知识的人能够提供帮助。