如何对Enum的__init__方法进行单元测试?

时间:2016-11-17 12:29:15

标签: python unit-testing enums

我正在努力在我正在使用的枚举上对__init__方法进行单元测试。困难在于我无法扩展枚举(所以不能隐含地调用__init__)。当我尝试从我的测试中直接调用它时,它坚持认为第一个参数应该是该枚举的实例。我不能这样做,因为我不能提前承担任何枚举的属性。

有一个人为的问题例子,假设我有一个偶数的枚举:

class EvenNumbers(Enum):
   two = 2
   four = 4

我想做一些值检查,以便没有人意外地为这个枚举添加一个奇数:

class EvenNumbers(Enum):
   two = 2
   four = 4

   def __init__(self, value):
      assert value % 2 == 0

现在我想编写一个测试来确保它有效。两种方法看似直观,但不起作用:

def test_approach_1():
    '''
    Try to extend the Enum with a bad value. This fails
    because I can't extend an Enum.
    '''

    class BadEnum(EvenNumbers):
        three = 3

def test_approach_2():
    '''
    Try to call the __init__ method directly. This fails
    because I need to supply an instance of the enum as
    the first parameter and I can't assume any values are
    available.
    '''

    EvenNumbers.__init__(None, 3)

我应该如何对__init__方法进行单元测试?

2 个答案:

答案 0 :(得分:2)

在测试一次性的Enum时(换句话说,您只有一个Enum类限制为偶数),那么只需测试Enum' s值:

for enum in EvenNumbers:
    self.assertTrue(enum.value % 2 == 0)

如果您希望在许多枚举中共享行为,或者正在测试的行为与成员的实际创建有关,那么只使用行为(没有成员)创建基类:

class EvenNumbers(Enum):
    def __init__(self, value):
        if value % 2 ! = 0:
            raise ValueError('%d is not an even number' % value)
    def double(self):
        return self.value * 2

然后您可以创建测试枚举:

class TestEvenEnum(unittest.TestCase):

    def test_bad_value(self):
        with self.assertRaises(ValueError):
            class NotEven(EvenNumbers):
                one = 1

    def test_good_value(self):
        class YesEven(EvenNumbers):
            two = 2
        self.assertEqual(YesEven.two.double(), 4)

答案 1 :(得分:1)

我目前正在使用的解决方案是将值检查逻辑放入空枚举中:

class EvenNumbersBase(Enum):
   def __init__(self, val): assert val % 2 == 0

class EvenNumbers(EvenNumbersBase):
   two = 2
   four = 4

这允许我测试EvenNumbers是否继承自EvenNumbersBase。我随后可以尝试使用不同的值扩展EvenNumbersBase来测试 init 方法。

这感觉就像跳过一些箍。你能建议一个更好的方法吗?