簡體   English   中英

如何編寫斷言語句來測試 ValueError

[英]How to write assert statements to test for ValueError

我為 Enum 類編寫了以下內容

class AbstractBaseQuotation(object):
    @total_ordering
    class STATE(namedtuple("State", "human_readable path order_in_path description"), Enum):
        DRAFT = "Draft", "happy", 1, "Anything that is not sent to vendor"
        PENDING_VENDOR = (
            "Pending Vendor",
            "happy",
            2,
            "Anything that is in vendor inbox",
        )
        
        CANCELLED = (
            "Cancelled",
            "cancel",
            None,
            "Any Order past the Draft stage can be cancelled",
        )

        @property
        def db_value(self):
            """
            Opinionated decision to use the member name as the database value to store
            """
            return self.name

        def _is_cancelled(self):
            return self == AbstractBaseQuotation.STATE.CANCELLED

        def __lt__(self, other):
            if (
                self.__class__ is AbstractBaseQuotation.STATE.DRAFT.__class__
                and self._is_cancelled()
            ):
                raise ValueError("Cannot compare CANCELLED with other states")
            if (
                other.__class__ is AbstractBaseQuotation.STATE.DRAFT.__class__
                and other._is_cancelled()
            ):
                raise ValueError("Cannot compare CANCELLED with other states")
            if self.__class__ is other.__class__:
                return self.order_in_path < other.order_in_path
            return NotImplemented

這是我的單元測試

   with self.assertRaises(ValueError) as raised:

       AbstractBaseQuotation.STATE.CANCELLED > AbstractBaseQuotation.STATE.DRAFT

我知道 assertRaises 期望什么是可調用的。 但我不知道如何測試

我也試過這個:

def test_compare_across_states(self):
    with self.assertRaises(ValueError) as raised:

        def compare():
            return AbstractBaseQuotation.STATE.CANCELLED > AbstractBaseQuotation.STATE.DRAFT

        compare()

兩次我都收到AssertionError: ValueError not raised

在這種情況下如何測試 ValueError ?

如果不給我們更多代碼,就很難推理出您的問題。 我假設它的樣子並嘗試了自己。 測試通過,所以我無法復制發生在你身上的事情。

from enum import IntEnum, Enum
import pytest


class KimEnum(IntEnum):
    CANCELLED = 1
    OTHER = 2

    def _is_cancelled(self):
        return self == self.CANCELLED

    def __lt__(self, other):
        if self._is_cancelled():
            raise ValueError
        raise RuntimeError("Should not reach this")


class EnumHolder:
    STATE = KimEnum


def test_kim_enum():
    assert KimEnum.CANCELLED == 1

    with pytest.raises(ValueError):
        _ = KimEnum.CANCELLED < 2


def test_enum_holder():
    assert EnumHolder.STATE.CANCELLED == 1

    with pytest.raises(ValueError):
        _ = EnumHolder.STATE.CANCELLED < 2

感謝@kszl 評論,我想我破解了

   def _flag_for_cancelled(self, other):
        if (
            self.__class__ is AbstractBaseQuotation.STATE.DRAFT.__class__
            and self._is_cancelled()
        ):
            raise ValueError("Cannot compare CANCELLED with other states")
        if (
            other.__class__ is AbstractBaseQuotation.STATE.DRAFT.__class__
            and other._is_cancelled()
        ):
            raise ValueError("Cannot compare CANCELLED with other states")

    def __lt__(self, other):
        self._flag_for_cancelled(other)
        if self.__class__ is not other.__class__:
            return NotImplemented
        return self.order_in_path < other.order_in_path

    def __gt__(self, other):
        self._flag_for_cancelled(other)
        if self.__class__ is not other.__class__:
            return NotImplemented
        return not self.__lt__(other)

    def __le__(self, other):
        self._flag_for_cancelled(other)
        if self.__class__ is not other.__class__:
            return NotImplemented
        return not self.__gt__(other)

    def __ge__(self, other):
        self._flag_for_cancelled(other)
        if self.__class__ is not other.__class__:
            return NotImplemented
        return not self.__lt__(other)

這是單元測試。 顯然 NotImplemented 會觸發 TypeError

def test_compare_across_states(self):
    # this is for greater than
    with self.assertRaises(ValueError):
        _ = AbstractBaseQuotation.STATE.CANCELLED > AbstractBaseQuotation.STATE.DRAFT
    with self.assertRaises(ValueError):
        _ = AbstractBaseQuotation.STATE.DRAFT > AbstractBaseQuotation.STATE.CANCELLED
    with self.assertRaises(TypeError):
        _ = AbstractBaseQuotation.STATE.DRAFT > 7

    # ge
    with self.assertRaises(ValueError):
        _ = AbstractBaseQuotation.STATE.CANCELLED >= AbstractBaseQuotation.STATE.DRAFT
    with self.assertRaises(ValueError):
        _ = AbstractBaseQuotation.STATE.DRAFT >= AbstractBaseQuotation.STATE.CANCELLED
    with self.assertRaises(TypeError):
        AbstractBaseQuotation.STATE.DRAFT >= 7

    # this is for less than
    with self.assertRaises(ValueError):
        _ = AbstractBaseQuotation.STATE.CANCELLED < AbstractBaseQuotation.STATE.DRAFT
    with self.assertRaises(ValueError):
        _ = AbstractBaseQuotation.STATE.DRAFT < AbstractBaseQuotation.STATE.CANCELLED
    with self.assertRaises(TypeError):
        AbstractBaseQuotation.STATE.DRAFT < 7

    # le
    with self.assertRaises(ValueError):
        _ = AbstractBaseQuotation.STATE.CANCELLED <= AbstractBaseQuotation.STATE.DRAFT
    with self.assertRaises(ValueError):
        _ = AbstractBaseQuotation.STATE.DRAFT <= AbstractBaseQuotation.STATE.CANCELLED
    with self.assertRaises(TypeError):
        AbstractBaseQuotation.STATE.DRAFT <= 7

暫無
暫無

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

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