5

所以标准的敏捷哲学会建议让你的域类成为简单的 POCO,这些 POCO 通过数据访问对象使用单独的代理层进行持久化(就像 NHibernate 那样)。它还建议获得尽可能高的单元测试覆盖率。

为这些简单的 POCO 对象编写测试是否有意义?假设我有一个看起来像这样的类:

public class Container {
 public int ContainerId { get; set;}
 public string Name { get; set;}
 public IList<Item> Contents { get; set;}
}

我可以为此编写哪些有用的单元测试?

4

5 回答 5

16

通常,像这样的值对象不需要有自己的测试。您将从使用它来实际做某事的类中获得报道。

单元测试旨在测试行为。没有行为?不需要测试。

于 2008-11-15T22:14:20.347 回答
7

实际上,我认为如果您在编写类之前就开始为此代码编写测试,那么您的实现会有所不同。例如,您可能最终会编写一个构造函数来初始化您的集合,这样您就可以引用它而不必每次都检查 null。我认为编写测试可能是一个好习惯,即使您认为不需要它们。通常在编写测试时,您会发现您所做的许多假设在您的第一次代码尝试中无法解决。

例如,ContainerId 可以小于零吗?尝试将其设置为负值会是错误吗?集合是否应该由构造函数初始化,即,使用此容器类的类是否必须在访问之前检查 null 还是要保证集合永远不会为 null,尽管它可能为空?

也就是说,我通常会在这个过程中应用一些理智。例如,如果我知道构造函数是内部作用域的,并且对象仅由 Factory 类创建。我将测试工厂方法以确保它们始终生成合法对象,但不一定要测试容器类本身。

无论如何,我想底线是假设类需要测试,尝试编写它们,并且只有在我想不出有意义的测试来编写时才省略它们。

于 2008-11-15T22:03:49.603 回答
3

这只是我的习惯,我绝不是这一切的全部,但我不会编写测试,直到我有一个实际做某事的构造函数(即设置默认值)。

您需要测试自己的代码,而不是语言。每当您使用 new Container() 时,您都会得到保证,您将获得一个新的 Container。而且,如果你确实搞砸了那一步,编译器就会捕捉到它。

于 2008-11-15T21:37:39.173 回答
1

我喜欢将单元测试视为“调用”一个意图单元。

您的代码表达的唯一意图是 getter 和 setter;作为语言的一部分,我们假设这些工作。

没有表达其他意图,因此不需要测试。

但是,我建议从Contents属性中删除 setter。集合属性应该是只读的。

于 2008-11-15T21:45:43.883 回答
0

我认为这甚至不是一个对象——对象是由它的行为定义的,而这个类没有任何东西。它是一个纯数据容器。也可以拥有这些 - 而且它们通常不需要任何测试 - 但请注意,您最终不会得到Anemic Domain Model。使用测试驱动开发会“迫使”你首先考虑你的类的行为,这可能是一个很好的练习。

于 2008-11-16T14:56:22.650 回答