【发布时间】:2012-12-27 00:29:59
【问题描述】:
我对单元测试真的很陌生,虽然我在研究上花费了大量时间,但我无法找到适合我的案例的正确方法。
我的代码库很大(大约 3 年的工作),不幸的是耦合度很高,很难测试,而且从来没有对它进行过单元测试。
例如,当尝试测试集合类ProductCollection,更具体地说,它的bool MoveElementAtIndex(Product productToMove, int newIndex) 时,我遇到了以下问题:
- 首先我必须初始化这个
new ProductCollection() - 构造函数初始化另一个手工类:
new KeyedList<ID, Product>。我想这不应该在这个构造函数中调用,因为我没有测试KeyedList。 - 接下来,我正在尝试将 3 个产品添加到此
ProductCollection。 - 然后我首先创建这 3 个
new Product()。 - 但是
Product类的构造函数做了几件事 - 它为新创建的产品计算一个唯一 ID:
this.ID = IDUtils.ComputeNewIDBasedOnTheMoonPhase()。我想我也不应该测试这个,因为它不是我的范围。我应该如何避免这种深度的调用? - 相同的 Product 构造函数为此产品分配了一些默认属性:
this.Properties = new ProductProperties(folderPathToDefaultProperties)。这不应该从我简单的FieldCollection.MoveElementAtIndex测试中调用,对吧? - 假设我现在终于有了我的产品对象,我正在尝试将它们添加到我的收藏中。
- 但是
ProductCollection.Add(MyProduct)检查底层KeyedList是否已经包含该产品。这也是我应该避免的业务逻辑,与我的测试无关。问题是如何? - 此外,在这个
Add方法中,会引发一些事件,通知系统一些事情(例如,新产品已添加到集合中)。我想这些也不应该被解雇。 - 最后,当我添加我的产品时,我将调用所需的 SUT:移动元素方法。
- 但是这个方法也有可能超出我的测试范围的逻辑:它验证底层
KeyedList实际上包含这些字段,它调用KeyedList.Remove(),KeyedList.Insert()的移动逻辑,它触发事件喜欢CollectionModified。
如果您能解释一下如何正确地进行此单元测试,如何避免调用底层对象,我将不胜感激。
我正在考虑微软的 Moles 框架 (VS2010),因为我的印象是它不需要我重构所有东西,因为这绝对不是一个选择。但是已经试过了,还是找不到合适的使用方法。
另外,我的印象是,这个具体的例子会在我的情况下帮助很多人,因为现实世界中的代码通常是这样的。
有什么想法吗?
【问题讨论】:
标签: c# unit-testing mocking moles coupling