Pytest捕获FastAPI的HTTPException同值断言相等失败原因排查
问题根本原因
fastapi.exceptions.HTTPException 没有实现自定义的实例相等比较方法(__eq__),Python 对这类对象默认使用身份比较逻辑:只有两个变量指向内存中同一个对象实例时,== 判断才会返回 True。你代码里分别实例化了两个独立的 HTTPException 对象,哪怕二者的 status_code、detail 属性值完全一致,因为是不同的内存对象,相等判断永远返回 False。
你尝试用字符串形式比对失败的原因也很简单:调试时看到的 HTTPException(status_code=400, detail='Inactive user') 是对象的 __repr__ 方法输出(面向开发者的调试表示),而 str(exc_info.value) 调用的是对象的 __str__ 方法,HTTPException 的 __str__ 默认只返回 detail 字段的内容,和你写的比对字符串完全不匹配。
正确的测试断言写法
不需要新建一个异常实例做整体比对,直接校验捕获到的异常实例的对应属性即可:
def test_get_current_active_user_not_active(): user: models.User = UserFactory() user.is_active = False with pytest.raises(HTTPException) as exc_info: get_current_active_user(current_user=user) assert exc_info.value.status_code == 400 assert exc_info.value.detail == "Inactive user"
如果你想在pytest.raises里直接完成内容匹配,也可以给它传match参数做异常内容的正则匹配,但注意match匹配的是异常的str()输出也就是detail内容,状态码还是需要单独断言:
def test_get_current_active_user_not_active(): user: models.User = UserFactory() user.is_active = False with pytest.raises(HTTPException, match="Inactive user") as exc_info: get_current_active_user(current_user=user) assert exc_info.value.status_code == 400
内容的提问来源于stack exchange,提问作者Aleksander Niemirka
相关产品推荐
相关产品推荐

