首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >单元测试:如何使用大量底层对象和业务逻辑测试方法

单元测试:如何使用大量底层对象和业务逻辑测试方法
EN

Stack Overflow用户
提问于 2013-01-12 15:36:30
回答 4查看 1.3K关注 0票数 3

我对单元测试非常陌生,虽然我花了大量的时间在研究上,但我无法找到适合我的情况的正确方法。

我的代码库非常庞大(大约3年的工作时间),不幸的是,很难进行测试,也从来没有对其进行过单元测试。

因此,例如,在尝试测试集合类ProductCollection (更具体地说,它的bool MoveElementAtIndex(Product productToMove, int newIndex) )时,我遇到了以下问题:

  • 首先,我必须初始化这个new ProductCollection()
  • 构造函数初始化另一个手工创建的类:new KeyedList<ID, Product>。我认为不应该在这个构造函数中调用它,因为我没有测试KeyedList
  • 接下来,我尝试向这个ProductCollection添加3种产品。
  • 然后,我首先创建这3 new Product()
  • 但是Product类的构造函数做了几件事
  • 它计算新创建的产品:this.ID = IDUtils.ComputeNewIDBasedOnTheMoonPhase()的唯一ID。我想我也不应该测试这个,因为这不是我的范围。在这种深度下,我应该如何避免这样的呼吁呢?
  • 相同的产品构造函数为该产品分配了一些默认属性:this.Properties = new ProductProperties(folderPathToDefaultProperties)。这不应该从我的简单FieldCollection.MoveElementAtIndex测试中调用,对吗?
  • 假设我现在终于有了我的产品对象,我正在尝试将它们添加到我的收藏中。
  • 但是ProductCollection.Add(MyProduct)检查底层KeyedList是否已经包含了该产品。这也是我应该避免的业务逻辑,与我的测试无关。问题是怎么做?
  • 此外,在这个Add方法中,会引发一些事件,通知系统一些事情(例如,向集合添加了一个新产品)。我认为也不应该发射这些武器。
  • 最后,当我添加我的产品时,我调用所需的SUT: move elements方法。
  • 但是这个方法也有可能超出我测试范围的逻辑:它验证底层的KeyedList实际上包含这些字段,它调用KeyedList.Remove(),调用KeyedList.Insert()作为其移动逻辑,并触发像CollectionModified这样的事件。

如果您能解释一下如何正确地进行这个单元测试,如何避免底层对象被调用,我将非常感激。

我想到的是微软的Moles (VS2010),因为我的印象是它不需要我重构所有东西,因为这绝对不是一种选择。但是已经试过了,仍然找不到合适的方法来使用它。

而且,我有这样的印象,这个具体的例子将对我的处境中的许多人有所帮助,因为现实世界中的代码就是这样的。

有什么想法吗?

EN

回答 4

Stack Overflow用户

发布于 2013-01-12 15:53:54

您的代码在设计时没有考虑到单元测试,这使得这样做非常困难。我建议您正确地设计和单元测试您的新代码,并尝试重构最重要的事情,以便您可以对其进行单元测试。

示例:

但是Product的构造函数做了几件事。它计算新创建的产品的唯一ID : this.ID = IDUtils.ComputeNewIDBasedOnTheMoonPhase()。我想我也不应该测试这个,因为这不是我的范围。在这种深度下,我应该如何避免这样的呼吁呢?

要解决这个问题,您应该将一个接口IUtils传递给产品构造函数。要测试产品类,您可以创建一个IUtils的模拟,它返回一个设置值。你也可以用你的ProductProperties做同样的事情。

此外,在这个Add方法中,会引发一些事件,通知系统一些事情(例如,向集合添加了一个新产品)。我认为也不应该发射这些武器。

这取决于设计。您可以使用观察者模式,而在单元测试时没有任何观察者。

票数 4
EN

Stack Overflow用户

发布于 2013-01-12 16:00:01

这是一个常见的问题,也是为什么我们有框架来为我们伪造对象。存根或模拟允许我们在类周围创建测试工具,而不必实例化许多其他类和服务。有许多suchh框架。这是一个非常有用的博客,包含三个常见的框架。http://www.richard-banks.org/2010/07/mocking-comparison-part-1-basics.html

我对单元测试非常陌生,并且发现的“单元测试的艺术”一书非常有用。罗伊有一个博客,这些是他在单元测试http://osherove.com/display/Search?moduleId=10002929&searchQuery=Unit+Testing上的一些帖子

需要考虑的另一件事是,您的类之间的耦合有多紧密。这可能不是那么容易做到,但您可能想看看依赖注入。这使得类可以更松散地耦合,因此更容易测试。我发现Mark在.NET中的“依赖注入”是一个很好的介绍。

在我的研究之后,我将NUnit作为测试框架,NSubstitute用于模拟和存根,流利断言使编写测试更容易,而NInject用于依赖注入

票数 2
EN

Stack Overflow用户

发布于 2013-01-12 16:01:12

我建议使用ApprovalTest。这是一个很好的工具来开始测试遗留系统,而不是最好的设计。

现在不要在单元测试和集成测试之间进行区分,也不要费心完全隔离类。您的代码可能并不最适合于可测试性,并且当您开始将所有内容彼此隔离时,您将得到大量的排列部分,并且测试非常脆弱。

另一方面,您必须隔离外部资源(web服务、数据库、文件系统等)。此外,所有不确定的行为都应该隔离(Random、当前时间、用户输入等等)。

我只是建议创建一个验证测试的安全网,这将帮助您在可测试性的方向上更改软件,并将告诉您是否对代码进行了彻底的更改。

读迈克尔羽毛有效地使用遗产代码

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14294861

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档