我建议你绝对应该。
什么是今天的自动财产,明天可能最终会有一个反对它的支持领域,而不是你……
“您只是在测试编译器或框架”的论点有点像稻草人恕我直言。从调用者的角度来看,测试自动属性时所做的是测试类的公共“接口”。调用者不知道这是具有框架生成的后备存储的自动属性,还是 getter/setter 中有一百万行复杂代码。因此,调用者正在测试该属性所暗示的合同——如果你将 X 放入盒子中,你可以稍后取回 X。
因此,我们应该包含一个测试,因为我们正在测试我们自己代码的行为,而不是编译器的行为。
像这样的测试可能需要一分钟的时间来编写,所以它并不十分繁琐;并且您可以轻松地创建一个 T4 模板,该模板将通过一些反思为您自动生成这些测试。我现在实际上正在开发这样一个工具来为我们的团队节省一些苦差事
如果你正在做纯 TDD,那么它会迫使你停下来考虑一下拥有汽车公共财产是否是最好的事情(提示:通常不是!)
难道您不想进行前期回归测试,以便当 FNG 执行以下操作时:
//24-SEP-2013::FNG - put backing field for ConnectionString as we're now doing constructor injection of it
public string ConnectionString
{
{get { return _connectionString; } }
{set {_connectionString="foo"; } }//FNG: I'll change this later on, I'm in a hurry
}
///snip
public MyDBClass(string connectionString)
{
ConnectionString=connectionString;
}
你马上就知道他们弄坏了东西?
如果上面的内容似乎是针对一个简单的字符串属性而设计的,那么我个人曾见过这样一种情况,即自动属性被认为自己非常聪明并想将其从实例成员更改为静态类成员的包装器的人重构(表示发生的数据库连接,更改的原因并不重要)。
当然,这个非常聪明的人完全忘记告诉其他人他们需要调用一个魔法函数来初始化这个静态成员。
这导致应用程序编译并发送给客户,因此它立即失败。没什么大不了的,但它花费了几个小时的支持时间==金钱.... 顺便说一句,那个布偶就是我!
编辑:根据该线程上的各种对话,我想指出对读写属性的测试非常简单:
[TestMethod]
public void PropertyFoo_StoresCorrectly()
{
var sut = new MyClass();
sut.Foo = "hello";
Assert.AreEqual("hello", sut.Foo, "Oops...");
}
编辑:你甚至可以按照 Mark Seeman 的Autofixture在一行中完成
我认为,如果你发现你有如此多的公共属性,以至于每写 3 行像上面这样都是一件苦差事,那么你应该质疑你的设计;如果您依靠另一个测试来表明此属性存在问题,那么要么
- 测试实际上是在测试这个属性,或者
- 您将花费更多时间来验证其他测试是否因为属性不正确(通过调试器等)而失败,而不是您在上面的代码中输入所花费的时间
- 如果其他一些测试允许您立即判断该属性有问题,那么它不是单元测试!
编辑(再次!):正如评论中指出的那样,生成的 DTO 模型之类的东西可能是上述情况的例外,因为它们只是用于将数据转移到其他地方的愚蠢的旧桶,而且因为工具创建了它们,测试它们通常是没有意义的。
/编辑
最终,“视情况而定”可能是真正的答案,但需要注意的是,最好的“默认”处置是“总是这样做”的方法,但在知情的情况下逐案处理除外。