在单元测试中进行模拟时,数据库/实体框架和内存列表之间的差异

本文关键字:内存 框架 列表 之间 实体 单元测试 模拟 数据库 | 更新日期: 2023-09-27 18:28:55

我最近用mocking做了很多单元测试。有一件事让我觉得有点问题,那就是(通过模拟我的存储库)对内存中的列表进行查询和通过实体框架直接对数据库进行查询之间的区别。

其中一些情况可能是:

  1. 测试对数据库不区分大小写但区分大小写的筛选器参数防止内存中的集合导致错误失败。

  2. Linq语句可能通过内存中的集合,但在实体框架中会失败,因为它们不受支持,导致错误通过。

处理或解释这些差异的正确方法是什么,这样在测试中就不会出现错误通过或失败?我真的很喜欢嘲笑,因为它让测试变得更快、更容易。但在我看来,获得真正准确测试的唯一方法是针对实体框架/数据库环境进行测试。

在单元测试中进行模拟时,数据库/实体框架和内存列表之间的差异

除了单元测试之外,您还应该创建集成测试,这些测试在生产中遇到的实际数据库设置中运行。

我不是EF的专家,但以NHibernate为例,您可以创建一个指向SQLite内存实例的配置,然后在该实例中运行快速测试(即在开发周期中,您希望尽快完成测试套件)。当您想针对真实的数据库运行集成测试时,只需更改NHibernate配置以指向真实的数据库设置,然后再次运行相同的测试。

如果你不能用EF取得类似的成绩,那将是令人惊讶的。

你可以使用DevMagicFake,这个框架会为你伪造数据库,还可以生成数据,这样你就可以在不测试数据库的情况下测试你的应用程序

首先也是最重要的一点是,您可以在mock中定义任何行为数据。其次是速度。从单元测试的角度来看,测试速度很重要。数据库连接在大多数时候都是瓶颈,所以这就是为什么要用测试来模拟它。为了正确地实施测试,你需要首先对你的整体拱门进行测试。例如,为了访问数据层,我有时会使用存储库模式。埃里克·埃文斯的DDD书中对它的描述非常好。假设您的存储库定义如下接口IRepository:IQueryable,ICollection您可以非常直接地处理linq查询。进一步阅读存储库

我会让mock更细粒度,这样你就不会在mock存储库中查询更大的集合。我通常在我的模拟存储库上设置setter,我在每次测试中都设置这些setter来控制模拟存储库的输出。这样,您就不必依赖于针对通用mock编写查询,并且您的重点可以放在测试中的方法

中的逻辑上