假设我们正在设计一个堆栈类测试优先(TDD):

public class Stack<T> {
    private T[] elements = new T[16];
    private int size = 0;
    ...
}

该堆栈利用16个内部阵列来存储其元素。它可以正常工作,直到您需要添加17个元素为止。由于我可能需要第17个元素,因此我决定将该功能添加到堆栈中,因此我开始思考我可以给测试的名称,必须添加该功能。那将是我的主题 第一个问题.

我首先选择了一些形式:

Should_Be_Able_To_Correctly_Increase_Its_Inner_Array_Size()

接着

Should_Handle_More_Items_Than_The_Default_Internal_Array_Size()

但是经过一会儿,我得出的结论是,以下内容可能更适合:

Should_Double_Its_Size_Every_Time_Its_Full()

我的推理必须在第一种情况下做到这一点,我只是说它的作用,而不是什么时候。在第二个中,我说何时添加更多物品,但我还指出我正在考虑如何(在内部)实现它,这可能是不正确的。在我看来(我不确定自己是正确的),我的测试应与外部的SUT相互作用,而不是在内部实现的方式上。我对吗?

在我看来,第三种选项是最好的,因为它清楚地说明了它的作用(实际上,它的尺寸增加了两倍),当它做到时(当时已经满),并且不将我与任何特定的特定联系在一起实现(我可能以后可能想将其更改为内部arraylist!)。

这使我走向我 第二个问题: :假设我为使用内部数组的堆栈类做了所有的单位测试-结构体?还是应该以任何方式进行测试?我猜不,但我不确定。

有帮助吗?

解决方案

在我看来(我不确定自己是正确的),我的测试应与外部的SUT相互作用,而不是在内部实现的方式上。我对吗?

你是对的。如果您更改类的内部实现,则该单元测试应保持不变。如果您在外部展示新的东西,则应创建新的单元测试来说明这些更改。

请记住,当您设计班级时,您不想公开任何指示其实施方式的内容。班级的公共成员表示如何与之互动,现在它如何在幕后工作。

其他提示

我不确定如何通过单元测试测试内部列表或数组大小。您无法通过堆栈接口访问它。单位测试用于测试外部合同。如果要测试实现详细信息,请尝试其他方法。

您的第二个问题的答案是肯定的,如果是单位测试,则测试仍应通过。

问问自己您愿意为这堂课承诺什么。

您或班级的消费者是否真的在乎容量的加倍,增加一倍或增加一千?如果是这样,您应该修改界面,以便他们可以指定用于增加容量的策略:

public Stack<T>(CapacityGrowthStyle capacityGrowthStyle) { ... }

如果没有 X 以下是您的基本数据结构的限制):

[Test]
public void Can_Handle_X_Items() { ... }

[Test]
[ExpectedException(typeof(InvalidOperationException))]
public void Cannot_Handle_More_Than_X_Items() { ... }

我会类似地回答您的第二个问题:您的测试只能反映您的班级用户关心的基础数据结构。

我不确定你是否 应该 通过单元测试测试内部列表或数组大小,因为您无法通过堆栈接口访问它。有很多方法可以实施堆栈,有些好,有些坏,但是正如伯纳德所说,这些是内部实现。单位测试旨在向外测试面向功能。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top