簡體   English   中英

Pytest 引發異常但斷言沒有捕獲它,盡管它們是相同的類型和相同的值

[英]Pytest raises exception but assert doesn't catch it, although they are the same type and same value

我正在為此功能編寫測試:

def get_current_active_user(current_user: models.User = Depends(get_current_user)) -> models.User:
    if not current_user.is_active:
        raise HTTPException(status_code=400, detail="Inactive user")
    return current_user

我正在嘗試檢查 HTTPException 的參數是否正確。 那是我的測試:

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 == HTTPException(status_code=400, detail='Inactive user')

出於某種原因,這個斷言永遠不會正確,盡管值是相同的。 調試會話:

>exc_info.value
HTTPException(status_code=400, detail='Inactive user')

>type(exc_info.value)
<class 'fastapi.exceptions.HTTPException'>

>type(HTTPException(status_code=400, detail='Inactive user'))
<class 'fastapi.exceptions.HTTPException'>

>exc_info.value == HTTPException(status_code=400, detail='Inactive user')
False

>str(exc_info.value) == "HTTPException(status_code=400, detail='Inactive user')"
False

非常感謝任何想法為什么會發生這種情況。

==在 python 中可能只是比較對象的 id,這就是相等性在這里失敗的原因。

也許您應該嘗試以下方法:

assert exc_info.value.status_code == 400
assert exc_info.detail == 'Inactive user'

Python 異常比較不相等:

In [8]: from starlette.exceptions import HTTPException

In [9]: e1 = HTTPException(status_code=400, detail="Inactive user")

In [10]: e2 = HTTPException(status_code=400, detail="Inactive user")

In [11]: e1 == e2
Out[11]: False

不僅僅是小星星:

In [12]: e3 = ValueError("wtf")

In [13]: e4 = ValueError("wtf")

In [14]: e3 == e4
Out[14]: False

如果要進行字符串比較,則必須使用repr

In [15]: str(e1)
Out[15]: ''

In [16]: repr(e1)
Out[16]: "HTTPException(status_code=400, detail='Inactive user')"

但更好的是只比較預期的異常屬性( pytest.raises已經確保它是預期的類型)

assert exc_info.value.status_code == 400
assert exc_info.detail == 'Inactive user'

正如其他人指出的那樣,您不能將==符號與異常實例一起使用。 Pytest 在 raises 函數中提供了match關鍵字,如果你想匹配異常的字符串表示,可以使用它。

with pytest.raises(HTTPException, match=r"HTTPException(status_code=400, detail='Inactive user')") as exc_info:
    get_current_active_user(current_user=user)

此處不能直接比較,嘗試與assert一起使用。 這將起作用。


assert exc_info.value.status_code == 400
assert exc_info.detail == "Inactive user"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM