“单元测试”具体会测试什么内容呢?考虑到典型的数据访问层(DAL)代码很少超出将实际工作委托给第三方数据访问代码(ADO.NET、EntityFramework、NHibernate)的范畴。
我并没有太多使用ADO.NET的经验,但我想这个NHibernate示例足以说明问题:
public User GetUser(int id)
{
using (var session = sessionFactory.OpenSession())
{
return session.Get<User>(id);
}
}
当然,假设代码编写正确,所有依赖项(即
sessionFactory
)都将通过接口传递,因此很容易进行存根,因此编写单元测试是可行的(您只需要模拟大量内容使其发生)。
纯粹的方法是编写这样的单元测试,因为它是证明您的代码确实执行您所假定操作(调用
Get
)的另一个数据点。但是,请注意,这样的测试相当昂贵,因为您基本上必须存根提供程序所进行的整个数据库访问(模拟
sessionFactory
以返回模拟会话,然后检查所做的调用)。
这是一个难以做出的决定(是否在这种情况下遵循纯粹的方法),因为您仍然需要编写带有真实数据库的
integration tests。而那些测试将涵盖与您编写的单元测试完全相同的领域,但在实际环境中工作(而不是在存根环境中)。
根据我的经验,对DAL进行单元测试通常不值得它提供的好处,特别是与其相对较高的成本(花费时间编写用于存根数据库环境的代码)和适当的集成测试套件的存在相比。
最后,我建议不要在任何类型的测试中使用内存数据库。原因如下:
- 它很慢
- 它有几个可能失效的点,可能很难控制(ORM配置、内存数据库设置、可能无效的测试数据)
- 给你一种错误的集成测试感觉(而实际上并非如此;内存数据库可能会表现出与您的真实生产数据库完全不同的行为)
除非您能够将完全相同的数据库加载到内存中,否则请坚持使用适当的集成测试(即DAL测试优先),并进行孤立的单元测试备份(只有在您负担得起编写它们的情况下)。