在没有实际访问数据库的情况下测试使用 Prisma 的 NestJS 服务

Posted

技术标签:

【中文标题】在没有实际访问数据库的情况下测试使用 Prisma 的 NestJS 服务【英文标题】:Testing a NestJS Service that uses Prisma without actually accessing the database 【发布时间】:2022-01-10 16:22:42 【问题描述】:

我见过的大多数关于如何测试 Prisma 注入的 NestJS 服务的示例(例如 testing-nestjs 中的 prisma-sample)都是用于“端到端”测试。他们实际访问数据库,执行实际查询,然后在必要时回滚结果。

对于我目前的需求,我想实现较低级别的“集成”测试。

作为其中的一部分,我想从等式中删除 Prisma。我希望重点放在我的服务功能上,而不是数据库中的数据状态和 Prisma 的返回能力。

这种方法的一大优势是它无需为特定测试制作“设置”查询和“拆卸”/重置操作。相反,我想简单地手动指定我们期望 Prisma 返回的内容。

在一个由 NestJS、Prisma 和 Jest 组成的环境中,我应该如何做到这一点?


更新: testing-nestjs 项目的作者在 cmets 中指出该项目确实有an example of database mocking。看起来很好!其他人可能仍然有兴趣查看我链接到的 Gist,因为它包含一些其他有用的功能。

【问题讨论】:

如您所见,我已经添加了自己的答案。我很好奇其他人更喜欢什么其他方法。 By the way, that same testing-nestjs repo you linked, it has unit tests for prisma where the database is mocked(来源,我是作者) @JayMcDoniel 我以为你会看到这个! ???你能分享一个链接吗?我记得看到的只是似乎在数据库上执行实际查询的测试。也许我只是误解了。 我在移动设备上没有看到链接 - 我去看看! 啊啊啊我现在明白了——我以为 repo 只有 e2e 测试。这很棒;谢谢,杰! 【参考方案1】:

要获取对服务的 prisma 实例的引用,请使用:

prisma = module.get<PrismaService>(PrismaService)

那么,假设你的函数调用prisma.name.findMany(),你可以使用jest.fn().mockReturnValueOnce()来模拟(手动指定)Prisma的下一个返回值:

prisma.name.findMany = jest.fn().mockReturnValueOnce([
     id: 0, name: 'developer' ,
     id: 10, name: 'architect' ,
     id: 13, name: 'dog walker' 
]);

(当然,您可以更改上面代码中的prisma.name.findMany 以匹配您正在调用的任何函数。)

然后,调用您正在测试的服务上的函数。例如:

expect(await service.getFirstJob("steve")).toBe('developer');

就是这样!一个full code example can be found here。

【讨论】:

以上是关于在没有实际访问数据库的情况下测试使用 Prisma 的 NestJS 服务的主要内容,如果未能解决你的问题,请参考以下文章

prisma 基于哪个数据库服务器?

我可以在不使用 prisma 的情况下在我的 graphQL 服务器中使用 MongoDB 吗?

如何在没有实际部署的情况下测试 DACPAC 是不是可以部署

如何在没有实际合并的情况下测试合并

Prisma 读取数据 - 有没有更好的方法来读取嵌套数据?

xctest 此应用试图在没有使用说明的情况下访问隐私敏感数据