你应该unit testing简单的属性?

你应该unit testing一个类的简单属性,声明一个值被设置和检索? 或者,这真的只是unit testing语言?

public string ConnectionString { get; set; } 

testing

 public void TestConnectionString() { var c = new MyClass(); c.ConnectionString = "value"; Assert.Equal(c.ConnectionString, "value"); } 

我想我没有看到那个价值。

我build议你绝对应该。

  • 什么是今天的汽车财产可能最终有明天的背后支持,而不是你呢…

  • “你只是testing编译器或者框架”这个说法有点像稻草人。 当你testing一个自动属性时你正在做的是从调用者的angular度来testing你的类的公共“接口”。 调用者不知道这是一个带有框架生成的后备存储的自动属性,或者getter / setter中有一百万行复杂的代码。 因此,调用者正在testing物业隐含合同 – 如果您将X放入箱中,稍后可以返回X.

  • 因此,由于我们正在testing我们自己的代码的行为,而不是编译器的行为,所以它应该包含一个testing。

  • 像这样的testing可能需要一分钟的时间,所以这不是一个繁重的工作。 你可以很容易地创build一个T4模板,将自动生成这些testing给你一些思考。 我现在实际上正在研究这样一个工具,为我们的团队节省一些苦差事

  • 如果你正在做纯粹的TDD,那么它会迫使你暂时停下来,考虑是否拥有汽车公共财产甚至是最好的事情(提示:通常不是!)

  • 你不愿意做一个先期的回归testing,以便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; } 

马上知道他们破了什么?

如果上面的代码看起来像一个简单的string属性,我个人看到了这样一种情况:一个自动属性被一个认为他们是如此聪明的人所重构,并希望将其从一个实例成员改变为一个静态类成员的包装(代表一个数据库连接发生的变化,并不重要)。

当然,这个聪明的人完全忘了告诉其他人他们需要调用一个神奇的函数来初始化这个静态成员。

这导致应用程序编译并发送给客户,因此它立即失败。 没有什么大不了的,但是花费了几个小时的时间==金钱……顺便说一下,那个混蛋是我的!

编辑:根据这个线程上的各种对话,我想指出,一个读写属性的testing是可笑的简单:

 [TestMethod] public void PropertyFoo_StoresCorrectly() { var sut = new MyClass(); sut.Foo = "hello"; Assert.AreEqual("hello", sut.Foo, "Oops..."); } 

编辑:你甚至可以按照Mark Seeman的Autofixture在一行中完成

我会提出,如果你发现你拥有如此大量的公共财产,就像写上面的三行一样,那么你应该质疑你的devise; 如果你依靠另一个testing来表示这个属性的问题,那么要么

  • testing实际上是testing这个属性,或者
  • 你将花费更多的时间来validation这个其他testing失败,因为属性是不正确的(通过debugging器等)比你在上面的代码中input
  • 如果其他一些testing可以让你立刻知道该属性是错误的,这不是一个unit testing!

编辑(再次)!正如在注释中指出的那样,正确地说,像生成的DTO模型之类的东西可能是上述的例外,因为它们只是用于将数据转移到其他地方的愚蠢的旧桶,另外,由于工具创build它们,testing它们通常是毫无意义的。

/编辑

一般来说,不。 应使用unit testing来testing单元的function。 你应该在一个类上unit testing方法,而不是单个的自动属性(除非你用自定义行为覆盖getter或setter)。

你知道,如果你得到正确的语法和设置值,那么把一个string值赋给一个自动的string属性就可以工作,因为这是语言规范的一部分。 如果你不这样做,那么你会得到一个运行时错误,指出你的缺陷。

unit testing应该被devise为testing代码中的逻辑错误,而不是编译器会捕获的东西。

编辑:根据我与这个问题的接受答案的作者的对话,我想补充以下内容。

我可以理解,TDD纯粹主义者会说你需要testing自动属性。 但作为一名商业应用程序开发人员,我需要合理地花费时间来编写和执行诸如自动属性之类的“微不足道”代码的testing,而不是合理花费多长时间来解决可能由没有testing。 在个人经验中,大部分由不断变化的代码引起的错误对于修复99%的时间是微不足道的。 出于这个原因,我认为只有unit testing的非语言规范function的好处超过了否定。

如果你在一个使用TDD方法的快节奏的商业环境中工作,那么该团队的工作stream程的一部分应该是只testing需要testing的代码,基本上是任何自定义代码。 如果有人进入你的class级,改变自动财产的行为,那么他们有责任在这个时候为其设置一个unit testing。

我不得不说不。 如果这不起作用,你就会遇到更大的问题。 我知道我不知道 现在有些人会认为,例如,如果删除了这个属性,单独使用代码就可以确保testing失败。 但是我会把钱放在这样一个事实上,即如果这个属性被删除了,那么unit testing代码就会在重构中被移除,所以没关系。

你是否坚持严格的TDD实践?

如果是,那么你绝对应该写公共getter和settertesting,否则你怎么知道你是否已经正确实施他们?

如果不是,你可能还是应该写testing。 尽pipe今天的实现是微不足道的,但不保证保持这种状态,并且如果没有testing覆盖简单的获取/设置操作的function,则当将来的实现改变打破了“设置具有值条的属性Foo的不变性”属性Foo的返回值Bar的getter“unit testing将继续通过。 testing本身也被简单地实施,但是防范未来的变化。

我所看到的是unit testing(或一般性testing)的多less取决于代码是如何devise的,以及未来破解的可能性。

如果你的代码破解的可信度较低(也许是由于代码不足,并且逐行检查的代价很高),那么unit testing属性可能是合适的。

一旦你能做的事情是编写一个帮助类,可以通过类的所有获取/设置属性来testing,他们仍然按照devise的行为。

除非属性执行任何其他types的逻辑,否则不。

是的,就像unit testing语言一样。 否则,testing简单的自动实现的属性将是完全没有意义的。

根据“ 使用.NET实例进行unit testing的艺术 ”一书,unit testing没有涵盖任何types的代码,而是关注逻辑代码 。 那么,什么是逻辑代码

逻辑代码是任何有一些逻辑的代码,它可能是小的。 这是逻辑代码,如果它有以下一个或多个:IF语句,循环,开关或案例语句,计算或任何其他types的决策代码。

简单的getter / setter是否包含任何逻辑? 答案是:

属性(Java中的getter / setter)是通常不包含任何逻辑的代码的好例子,因此不需要testing。 但要小心:一旦你在房产内添加任何支票,你就要确保逻辑正在被testing。

我的回答是从前testing经理的观点和目前的开发经理(负责软件交付的时间和质量)的观点。 我看到人们提到实用主义。 实用主义不是一个好的顾问,因为它可能会与懒惰和/或时间压力成对。 它可能导致你错误的方式。 如果你提到实用主义,你必须小心谨慎,保持你的专业精神和常识。 它需要谦卑接受答案,因为他们可能不是你想听到的。

从我的观点来看,重要的是下一个:

  • 你应该尽早find缺陷。 这样做,你必须应用适当的testing策略。 如果是testing属性,那么你必须testing属性。 如果没有,那就不要这样做。 两者都有一个价格。
  • 您的testing应该简单快捷。 在构build时testing的代码的更大的部分(单元,集成等)是更好的。
  • 您应该做根本原因分析来回答下面的问题,并使您的组织免受当前types的错误的影响。 别担心,会出现另一种缺陷,总会有教训要学习。
    • 根源是什么?
    • 下次如何避免?
  • 另一个方面是创build/维护testing的成本。 不testing性质,因为他们无聊维护和/或你有数百个属性是荒谬的。 你应该创造/应用工具,而不是人类的木刻作业。 一般来说,你总是必须改善你的环境,以提高效率。
  • 别的什么都不是好的顾问 – 无论Martin Fowler还是Seeman都说 – 他们的环境我相当肯定不一样,你必须用你的知识和经验来设置什么对你的项目是好的,如何使它更好。 如果因为别人的说法而使用了这些东西,甚至没有经过考虑,你就会发现自己陷入深重的困境。 我不是说你不需要build议和/或其他人的帮助或意见,你必须运用常识来运用它们。
  • TDD并没有回答两个重要的问题,但是,BDD确实给出了以下问题的答案。 但是,如果你只遵循一个,你将无法及时和质量地交付。 所以无论你是纯粹的TDD家伙还是没有。
    • 什么必须testing? (它说,一切都必须testing – 在我看来是错误的答案)
    • 什么时候testing一定要完成?

总而言之,没有好的答案。 只有其他问题,你必须回答,以获得临时的点,你可以决定是否需要。