如何在 Python 中模拟异常调用?

4 投票
1 回答
4047 浏览
提问于 2025-04-17 15:14

我有一段这样的代码:

def extract(data):
    if len(data) == 3:
       a = 3
    else:
        component = data.split("-")
        if len(component) == 3:
            a,b,c = component
        else:
            raise globals.myException("data1", "Incorrect format", data)

    return a,b,c

这是一个简化版。我想要模拟一个异常类 globals.myException。我是这样做的:

def test_extract_data_throws_exception(self):
        with patch('globals.myException') as mock: 
            mock.__init__("data1", "Incorrect format", "")
            with self.assertRaises(myException):
                self.assertEqual(extract(""), (""))

但是我总是遇到这个错误:“TypeError: 异常必须是旧式类或者是从 BaseException 继承的,而不是 MagicMock。”

补充说明:正如 @Aaron Digulla 所建议的,猴子补丁(monkey patching)是正确的解决方案。我发布这个解决方案是为了帮助其他人。

def test_extract_data_throws_exception(self):
        #monkey patching
        class ReplaceClass(myException):
            def __init__(self, module, message, detail = u''):
                pass

        globals.myException = ReplaceClass
        with self.assertRaises(myException:
            self.assertEqual(extract(""), (""))

1 个回答

4

原因是 raise 会检查你传入的参数类型。这个参数必须是一个字符串(也叫“旧式异常”)或者是从 BaseException 这个类派生出来的。

因为一个 mock 对象既不是字符串也不是从 BaseException 派生的,所以 raise 不会使用它。

在这种情况下,你要么直接抛出异常,要么使用 猴子补丁(也就是在你的测试中覆盖 globals.myException 这个符号,然后再恢复它)。

撰写回答