Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
单元测试简单方法。。。一个健全的OOP/Python解决方案?_Python_Oop_Unit Testing - Fatal编程技术网

单元测试简单方法。。。一个健全的OOP/Python解决方案?

单元测试简单方法。。。一个健全的OOP/Python解决方案?,python,oop,unit-testing,Python,Oop,Unit Testing,我试图以一种良好的面向对象的方式设计和测试类似于以下内容的代码?(还是一种蟒蛇式的方式?) 下面是一个工厂类,它决定一个人的名字是长是短: class NameLengthEvaluator(object): def __init__(self, cutoff=10) self.cutoff = cutoff def evaluate(self, name): if len(self.name) > cutoff:

我试图以一种良好的面向对象的方式设计和测试类似于以下内容的代码?(还是一种蟒蛇式的方式?)

下面是一个工厂类,它决定一个人的名字是长是短:

class NameLengthEvaluator(object):
    def __init__(self, cutoff=10)
        self.cutoff = cutoff

    def evaluate(self, name):
        if len(self.name) > cutoff:
            return 'long'
        else:
            return 'short'
下面是一个person类,它对自己姓名的长度有自己的看法:

 class Person(object):
     def __init__(self, name=None, long_name_opinion=8):
         self.name = name

     def name_length_opinion(self):
         return 'My names is ' + \
                    NameLengthEvaluator(long_name_opinion).evaluate(self.name)
有几个问题:

  • Person
    方法
    name\u length\u opinion()
    是否值得进行单元测试,如果是这样,它会是什么样子
  • 总的来说,有没有一种好方法可以测试具有完全外部功能的类的简单方法
似乎这个方法的任何测试都只是重申它的实现,并且测试的存在只是为了确认没有人接触代码


(免责声明:代码未经测试,我是python新手)

这实际上取决于代码的生命周期。很明显,在当前状态下,该方法显然是正确的,单元测试更像是对其行为的规范。如果您计划在将来进行更改(例如,以某种不同的方式重新实现
namelingtheevaluator
),那么进行单元测试是很好的,因为运行测试将捕获任何回归。但是在这种情况下,您似乎不太可能进行任何更改,因此测试可能过多(尽管进行了良好的健全性检查)。

单元测试 Person方法name_length_opinion()是否值得进行单元测试,如果是,它会是什么样子

你想确保它做你认为它做的事情,并确保它在未来不会破裂吗?如果是这样,请为其编写一个单元测试

测试只是为了确认没有人碰过代码

单元测试更多的是确保类符合它指定的契约。您不必为所有内容编写单元测试,但是如果它是一个简单的方法,那么无论如何它都应该是一个简单的单元测试

重复 似乎对该方法的任何测试都只是重申其实现

你不应该重复这个算法,你应该使用用例。例如,截止值为
10
名称长度估价者
应具有以下短名称:

  • 乔治
  • 玛丽
这些名字很长:

  • 麦基刀
  • 千斤顶
因此,您应该验证该方法是否正确地报告了这些名称的简短程度。您还应该测试一个
名称长度,在
4
截止值的情况下,评估者将报告
Mary
为短,其他为长

一次性代码? 如果您曾经编写过一个类,然后又编写了一个主方法来运行该类,以确保该类执行它应该执行的操作(然后在转到另一个类时将该主方法扔掉),那么您已经编写了一个单元测试。但是不要扔掉它,而是保存它并将其转换为单元测试,这样将来您就可以确保没有破坏任何东西

外部代码 总的来说,有没有一种好方法可以测试具有完全外部功能的类的简单方法


如果它完全是外部的,那么为什么它是这个类上的一个方法呢?通常,您至少有一些可以测试的逻辑。在这种情况下,您可以测试
name\u length\u opinion
是否在正确的情况下返回
My names is long
My names is short

通常您会在此处使用模拟。您可以创建一个模拟的
namelength评估器
,该评估器返回一个记录了连接内容的对象,当
name\u length\u opinion
返回时,您应该检查以确保使用了正确的对象并连接了正确的对象

例如,使用:

然而,由于方法如此简单,我不确定你是否会那么在意

from unittest.mock import MagicMock, patch

@patch('your_module.NameLengthEvaluator', autospec=True)
def test_person_name_length_opinion(NameLengthEvaluator):
    expected_result = object()
    opinion = MagicMock(name='opinion')
    opinion.__radd__.return_value = expected_result
    name_length_evaluator = MagicMock(name='name_length_evaluator')
    name_length_evaluator.evaluate.return_value = opinion
    NameLengthEvaluator.return_value = name_length_evaluator

    name = object()
    length_limit = object()

    person = Person(name, long_name_opinion=length_limit)
    result = person.name_length_opinion()

    NameLengthEvaluator.assert_called_with(length_limit)
    name_length_evaluator.evaluate.assert_called_with(name)
    opinion.__radd__.assert_called_with('My names is ')
    assert result is expected_result