测试 EF Core 应用程序
测试对于几乎所有类型的应用程序而言都很重要 - 通过测试可以确保应用程序正常运行,并能快速知道应用程序的行为在将来是否会发生回归。 由于测试可能会影响代码的构建方式,因此强烈建议尽早规划测试,并确保随着应用程序的发展实现良好的覆盖率。 本介绍性部分简要概述了使用 EF Core 的应用程序的各种测试策略。
涉及数据库(或不涉及)
在为 EF Core 应用程序编写测试时,需要做出的一个基本决定是,测试是否会像应用程序一样涉及生产数据库系统,或是否要针对一个测试替身来运行测试,后者用于替代生产数据库系统。 关于 EF Core 上下文中的测试替身的两个显著的例子是内存中 SQLite 模式和内存中提供程序。
有关不同方法的深入比较和分析,请参阅选择测试策略。 下面是一个简短的逐点摘要,可帮助你快速了解不同的选项:
- 开发人员经常会避免针对其生产数据库系统进行测试,因为他们认为这很难或很慢。 这在我们的体验中并不总是如此,我们建议为这种方法提供一种机会:针对生产数据库系统进行测试提供了可靠且高效地执行此操作的方法。 针对数据库编写至少一些测试在任何情况下通常都是必要的 - 这是为了确保应用程序能真正针对生产数据库正常运行 - 而不涉及数据库的测试可能会在测试内容上有一定限制(见下文)。
- 内存中提供程序在很多重要方面上的行为与实际数据库不同。 有些功能完全无法利用它进行测试(例如事务、原始SQL 等),而其他功能的行为可能会与生产数据库不同(例如,查询中区分大小写)。 虽然“内存中”可用于简单有限的查询方案,但其局限性较大,不建议使用。
- 通过模拟
DbSet
进行查询既复杂又困难,与“内存中”方法有相同的缺点;也不建议使用。
- 通过模拟
- SQLite 内存中模式提供更好的与生产关系数据库的兼容性,因为 SQLite 本身是一个功能完善的关系数据库。 但 SQLite 和生产数据库之间仍然会存在一些重要差异,某些功能是无法测试的(例如,EF.Functions 上的特定于提供程序的方法)。
- 为了能够对生产数据库系统的所有功能使用可靠的测试替身,可以尝试在应用程序中引入存储库层。 通过这种方法可以将 EF Core完 全排除在测试之外,并实现对存储库的完全模拟;但这可能会极大改变应用程序的体系结构,并需要更多的实现和维护成本。
其他阅读材料
有关更深入的信息,请参阅选择测试策略。 有关实现指南和代码示例,请参阅针对生产数据库系统进行测试和测试时不使用生产数据库系统。