何时模拟数据库访问

时间:2011-08-04 09:20:48

标签: database unit-testing testing mocking integration-testing

我在测试数据库调用时多次完成的是设置数据库,打开事务并在最后回滚它。我甚至使用了我在每次测试中创建和销毁的内存中的sqlite数据库。这工作并且相对较快。

我的问题是:我应该模拟数据库调用,我应该使用上面的技术还是应该同时使用两者 - 一个用于单元测试,一个用于集成测试(至少对我来说,似乎是双重工作。)

2 个答案:

答案 0 :(得分:7)

问题是,如果您使用设置数据库,打开事务和回滚的技术,您的单元测试将依赖于数据库服务,连接,事务,网络等。如果你嘲笑它,你的应用程序中没有依赖于其他代码片段,并且没有外部因素影响你的单元测试结果。

单元测试的目标是测试最小的可测试代码而不涉及其他应用程序逻辑。使用IMO技术时无法实现这一目标。

通过抽象数据层使代码可测试是一种很好的做法。它将使您的代码更健壮,更易于维护。如果实现存储库模式,则模拟数据库调用相当容易。

单元测试和集成测试也可满足不同需求。单元测试是为了证明一段代码在技术上是有效的,并且可以捕获角落案例。 集成测试根据软件设计验证组件之间的接口。仅单元测试无法验证软件的功能。

HTH

答案 1 :(得分:3)

所有我必须补充的是@Sphane的答案是:它取决于你如何将单元测试融入你自己的个人开发实践中。如果您有涉及真实数据库的端到端集成测试,您可以根据需要创建和整理 - 只要您已经涵盖了代码中的所有不同路径以及用户黑客发布数据时可能发生的各种可能性等等 - 从测试的角度来看你是否覆盖了你的系统是否正常工作,这可能是进行测试的主要原因。

我猜想,虽然每个测试都运行在系统的每一层都会让测试驱动的开发变得非常困难。需要每个层到位并且工作以便测试通过几乎不包括花几分钟写测试,几分钟使它通过,并重复。这意味着您的测试不能guide you就各个组件的行为和交互方式而言;例如,你的测试不会强迫你做松散耦合的事情。另外,假设您添加了一项新功能,并在其他地方发生单独针对组件运行的粒度测试可以更容易地跟踪出错的地方。

由于这些原因,我认为创建和维护集成和单元测试的“双重工作”是值得的,你的DAL在后者中被嘲弄或存根。