没有DI的单元测试遗留代码

时间:2014-08-05 15:05:46

标签: c# unit-testing legacy-code

我们正在尝试将单元测试添加到我们的业务层中。技术堆栈是asp.net Web表单,WCF,ADO.Net调用存储过程)。业务层在数据类上调用静态方法,因此很难在不进行大量更改的情况下引入DI。

这可能不是传统的方法,但我想将DB保持在单元测试(依赖)中,而是将其用作测试Db ...使用现有的冻结数据库或在表格中嘲笑数据。我想知道使用测试数据库的可行性,其中存储过程像Mocks一样使用。不要复制整个数据库,只需创建由存储过程命名的表名。 存储过程只调用一个表,并返回静态数据......本质上,尝试使用类似Moq但从DB角度模拟Mocking数据的功能。

任何人都可以推荐任何在测试中包含数据库的设计,这仍然是确定性的吗?

2 个答案:

答案 0 :(得分:1)

如果你想在测试中使用数据库并确保所有内容都是确定性的,那么你需要每个测试都有自己的数据库,这意味着为每个测试创建(并可能填充)一个新的数据库。

根据数据库层创建连接的方式,这是可行的。我通过在测试设置中使用localDb生成一个数据库,并使用名称的GUID,然后在拆除测试结束时再次删除数据库。

它最终变得相当慢(不足为奇)但是在Ram磁盘驱动器上创建数据库有助于此。

这适用于空dbs,然后有EF创建的模式,但如果你需要在数据库中有一组固定的数据,那么你可能需要在测试设置中从备份中恢复它

答案 1 :(得分:0)

在我看来,在为每个测试调用它们时,设置存储过程以执行您希望它们执行的操作会有很多工作,并且您仍然会遇到速度问题数据库总是存在。我建议您改为执行以下一项或两项操作:

  1. 使用TypeMock,它具有强大的隔离工具。它基本上改变了你的编译,使你的单元测试甚至可以模拟静态方法。
  2. 尝试创建"验收测试,而不仅仅是单元测试,"专注于模仿完整的用户体验:登录,创建对象,查看对象(验证对象看起来正确),更新对象,再次查看对象(同上),删除对象(验证对象被删除)。通过设置此特定测试所需的所有对象开始每个测试,并通过删除所有这些对象结束,以便其他测试可以基于假定的起始状态运行。
  3. 第一种方法为您提供真实"单位"的速度和可模仿性。测试,而第二个允许你运用更多的代码,增加你捕获错误的可能性,即使在存储过程之类的东西。