2013-03-15 127 views
1

我目前正在严重考虑我们的团队正在构建的单元测试一个asp.net mvc 3 web应用程序。单元测试:真正的数据库与嘲讽

问题是我们真的必须嘲笑很多东西,我认为我们的单元测试并没有涵盖所有与网络服务器和数据库相关的东西。

例子:

我有下面的代码的方法:

public List<Useraccount> GetUseraccounts(Company company) 
{ 
    return company.Useraccounts.ToList<Useraccount>(); 
} 

我devloper抱怨说,他有注射假的公司对象他通过hisself准备。 他想从数据库中获得真实的对象。

我的问题: 在单元测试期间是否可以使用真实数据库(也可以是SQLite/SQLExpress或其他)?这有用吗? 有什么优点和缺点?我们不得不模拟太多的对象。例如,我们无法验证此类呼叫是否正常工作:

Useraccount useraccount = UnitOfWork.UseraccountRepository.Get(u => u.EnableCode == enableCode && u.IsEnabled == false).Single<Useraccount>(); 
+2

听起来好像你可能模糊了* unit * testing和* integration * testing之间的界限。 – 2013-03-15 12:46:08

+0

含义是什么?真正的数据库内容仅用于集成测试? – mosquito87 2013-03-15 12:49:14

+0

我相信@四十二意味着你应该考虑两套测试。一个是关于单元测试,测试你的类做他们应该做什么,嘲笑依赖。然后,您可以进入下一级黑盒/集成测试,您可以在其中全面测试您的服务,但可以在需要的地方剔除第三方服务。 – Bronumski 2013-03-15 13:27:50

回答

0

尝试使用Effort工具。 Effort是一个功能强大的工具,它可以为基于实体框架的应用程序创建自动化测试提供方便的方式。 它基本上是一个ADO.NET提供程序,它在轻量级进程内存数据库而不是传统外部数据库上执行所有数据操作。它提供了一些直观的帮助程序方法,可以很容易地将此​​提供程序与现有的ObjectContext或DbContext类一起使用。对现有代码的简单添加可能足以创建可在没有外部数据库的情况下运行的数据驱动测试。

1

对真实数据库的测试是集成测试,而不是单元测试。您仍然可以像单元测试一样运行集成测试 - 也就是说,可以通过nunit或mstest或其他任何方式运行它们,也可以通过命令行或类似的方式在您的构建服务器上运行它们 - 但还有一些额外的步骤:

  1. 您需要设置测试数据,将其注入数据库,运行测试,然后再次删除测试数据。在理想的情况下,您可以在集成测试运行开始时创建测试数据库,然后运行所有测试,然后在所有集成测试完成后将其删除。这可能是不切实际的。

  2. 您的集成测试运行速度比单元测试慢得多。通过运行它们来为此做好准备,例如,每晚在构建服务器作业中运行它们。

在使用SqlLite或任何方面,我说不要,用你使用在现实世界数据库的确切类型,否则就不是一个值得信赖的测试。

+0

感谢您的回答。 基本上我们首先想要“完成”单元测试。我的感觉是它们不完整,因为我们无法在代码中测试很多行,因为实体框架。 – mosquito87 2013-03-15 13:28:20

+0

我想说这是一个罕见的应用程序,它可以仅使用单元测试覆盖所有(甚至大部分)数据访问代码行。话虽如此,你确定EF是否是问题,并且该代码不能被重新编译为单元测试? – 2013-03-15 14:12:17