Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/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
Unit testing 测试驱动开发:为私有/受保护变量编写测试_Unit Testing_Variables_Tdd_Private_Protected - Fatal编程技术网

Unit testing 测试驱动开发:为私有/受保护变量编写测试

Unit testing 测试驱动开发:为私有/受保护变量编写测试,unit-testing,variables,tdd,private,protected,Unit Testing,Variables,Tdd,Private,Protected,我正在学习TDD,我有一个关于私有/受保护变量的问题。我的问题是:如果我想测试的函数是在私有变量上运行的,我应该如何测试它 以下是我正在使用的示例: 我有一个名为Table的类,它包含一个名为internalRepresentation的实例变量,它是一个二维数组。我想创建一个名为multiplyValuesByN的函数,将2D数组中的所有值乘以参数n 因此,我为它编写了测试(用Python): 现在,如果我将internalRepresentation设为私有或受保护,则此测试将不起作用。我应

我正在学习TDD,我有一个关于私有/受保护变量的问题。我的问题是:如果我想测试的函数是在私有变量上运行的,我应该如何测试它

以下是我正在使用的示例:

我有一个名为
Table
的类,它包含一个名为
internalRepresentation
的实例变量,它是一个二维数组。我想创建一个名为
multiplyValuesByN
的函数,将2D数组中的所有值乘以参数
n

因此,我为它编写了测试(用Python):


现在,如果我将
internalRepresentation
设为私有或受保护,则此测试将不起作用。我应该如何编写测试,使其不依赖于
内部表示法
,但在调用
multiplyValuesByN
后仍然测试它是否正确?

您不应该依赖对象的内部表示法。这就是为什么它被标记为私有或受保护。当你调用T.MulthyValueSyn(3)时,考虑对T的可观察到的变化。然后,测试你能观察到的东西

def test_multiplyValuesByN (self):  
    t = Table(3, 3) # 3x3 table, filled with 0's
    t.set(0, 0, 4) # Set value at position (0,0) to 4
    t.multiplyValuesByN(3)

    assertEqual(t.get(0,0), 12)

不要测试私有变量/状态。您的测试应该确认被测试的单元符合其规范,并且该规范由其接口决定。因此,您的测试应该根据测试单元的输入编写,并验证输出是否与您期望的匹配


您希望能够更改被测试单元的实现(例如,出于效率原因),同时确认它按预期工作。因此,在这种情况下,检查私有状态会造成困难。

如果私有状态是内部的,那么在类之外就没有人做任何事情,包括测试

在TDD中,您正在设计类的API,未来的客户机也只能看到类的可观察行为

我知道这说起来容易做起来难

在测试中,您经常看到一个模式重复出现:设置-操作-检查(-teardown)

设置阶段负责使对象处于预条件状态


检查阶段应该通过类的可观察行为来验证后条件。如果看不见的状态永远也不会出现,那么存储它是没有意义的。

其他人给出了很好的答案,但我没有强调一点:设计方面(尽管Peter Tillemans提到了这一点)。所以我对这一点做了一些解释


在进行TDD时,您正在有效地测试API的设计和实现。如果您发现方法调用的结果很难或不可能从外部看到,这几乎总是表明您的类接口设计得不好。如果很难为类编写测试,那么在现实生活中也很难使用它——实际上,单元测试是类的第一批客户机。因此,如果你看到一个测试用例很难使用你的类接口,你应该考虑回去并重新设计你的API,以使它更容易使用(不妥协封装,如果可能)。这就是为什么我把它放在括号里。这是一个实际的东西,有时是需要的,但不符合理论。我喜欢3-A头韵。我以前没听说过,谢谢!
def test_multiplyValuesByN (self):  
    t = Table(3, 3) # 3x3 table, filled with 0's
    t.set(0, 0, 4) # Set value at position (0,0) to 4
    t.multiplyValuesByN(3)

    assertEqual(t.get(0,0), 12)