【问题标题】:Unit testing a method called during initialization?单元测试初始化​​期间调用的方法?
【发布时间】:2009-10-18 07:03:13
【问题描述】:

我有一个类似如下的课程:

class Positive(object):
    def __init__(self, item):
        self._validate_item(item)
        self.item = item

    def _validate_item(self, item):
        if item <= 0:
            raise ValueError("item should be positive.")

我想为_validate_item() 编写一个单元测试,如下所示:

class PositiveTests(unittest.TestCase):
    def test_validate_item_error(self):
        self.assertRaises(
            ValueError,
            Positive._validate_item,
            0
        )

不幸的是,这行不通,因为单元测试仅将 0 传递给方法,而不是类实例(对于 self 参数)和 0。除了必须对此进行测试之外,还有其他解决方案吗通过类的__init__()间接验证方法?

【问题讨论】:

    标签: python unit-testing oop testing


    【解决方案1】:

    如果您没有在方法的主体中使用 self,则暗示它可能不需要成为类成员。您可以将 _validate_item 函数移动到模块范围内:

    def _validate_item(item):
        if item <= 0:
            raise ValueError("item should be positive.")
    

    或者如果它真的必须留在类中,则将方法标记为静态:

    class Positive(object):
        def __init__(self, item):
            self._validate_item(item)
            self.item = item
    
        @staticmethod
        def _validate_item(item):
            if item <= 0:
                raise ValueError("item should be positive.")
    

    然后您的测试应该按照书面的方式进行。

    【讨论】:

    • 我喜欢这个答案。如果您觉得需要自己为 _validate_item() 编写测试,那么它实际上很可能属于自己。
    • 静态方法在 Python 中大多没有意义,在这种情况下使用类方法!
    • 我不会在这里使用@classmethod 装饰器,原因与我不会将其定义为实例方法的原因相同。 cls 没有用。鉴于我的 druthers,我会将其设为模块范围内的私有函数。
    【解决方案2】:

    您没有创建 Positive 实例。怎么样

    Positive()._validate_item, 0
    

    【讨论】:

    • 此代码引发 TypeError,因为 Positive.__init__() 缺少 item 参数。
    • 这表明您正在尝试测试实现“_validate_item”,而不是接口。我认为测试Positive(0) 比测试_validate_item(0) 好得多。
    • 以上评论是@gotgenes
    【解决方案3】:

    嗯,_validate_item() 是通过构造函数进行测试的。使用 null 或负值调用它会引发 ValueError 异常。

    退后一步,这就是目标,不是吗? “要求”是不应使用零或负值创建对象。

    现在这是一个人为的例子,所以上面不能适用于真实的类;另一种可能性,真正有一个专门用于 _validate_item() 方法的测试,可能是创建一个具有正值的对象,然后在其上调用 validate_item()。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多