You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NestAPI单元测试失败:findAll返回空数组与预期不符

问题

我正在为我的NestAPI编写单元测试。我的service.ts中有如下代码:

findAll(): Promise<Users[]> {
  return prisma.users.findMany();
}

在service.spec.ts中,我定义了测试数据:

const usersMany = [
  {
    username: 'user1',
    name: 'User One',
    password: '123',
    email: 'user1@test.com',
    tasks: [],
  },
  {
    username: 'user2',
    name: 'User Two',
    password: '456',
    email: 'user2@test.com',
    tasks: [],
  }
]

随后编写了findAll()的测试用例:

describe('findAll', () => {
  it('should return all users', async () => {
    const usersAll = await service.findAll();
    expect(usersAll).toEqual(usersMany);
  });
});

但运行测试时出现错误,实际返回空数组,与预期的用户列表不符:

- Expected  - 23
+ Received  +  1

- Array [
-   Object {
-     "email": "user1@test.com",
-     "name": "User One",
-     "password": "123",
-     "tasks": Array [],
-     "username": "user1",
-   },
-   Object {
-     "email": "user2@test.com",
-     "name": "User Two",
-     "password": "456",
-     "tasks": Array [],
-     "username": "user2",
-   },
- ]
+ Array []

我是单元测试新手,想知道测试失败的原因。

原因与解决方法

测试失败的核心原因是你直接调用了真实的Prisma客户端,而测试环境的数据库里没有预先插入usersMany中的测试数据,所以findMany()返回空数组。单元测试应该隔离依赖,不需要连接真实数据库,正确的做法是Mock Prisma客户端的users.findMany方法。

具体步骤如下:

  • 在测试文件中Mock Prisma服务
    在service.spec.ts里,需要先Mock PrismaModule,确保Service依赖的是Mock后的Prisma客户端,而不是真实实例。示例代码:
    import { Test, TestingModule } from '@nestjs/testing';
    import { UsersService } from './users.service';
    import { PrismaService } from '../prisma/prisma.service';
    
    describe('UsersService', () => {
      let service: UsersService;
      let prisma: PrismaService;
    
      beforeEach(async () => {
        const module: TestingModule = await Test.createTestingModule({
          providers: [
            UsersService,
            {
              provide: PrismaService,
              useValue: {
                users: {
                  findMany: jest.fn(), // Mock findMany方法
                },
              },
            },
          ],
        }).compile();
    
        service = module.get<UsersService>(UsersService);
        prisma = module.get<PrismaService>(PrismaService);
      });
    
  • 在测试用例中指定Mock方法的返回值
    修改findAll的测试用例,让Mock的findMany返回你定义的usersMany数据:
    describe('findAll', () => {
      it('should return all users', async () => {
        // 设定Mock方法的返回值
        jest.spyOn(prisma.users, 'findMany').mockResolvedValue(usersMany);
        
        const usersAll = await service.findAll();
        expect(usersAll).toEqual(usersMany);
        // 额外验证:确保findMany被调用了一次
        expect(prisma.users.findMany).toHaveBeenCalledTimes(1);
      });
    });
    
  • (可选)如果需要用真实数据库测试(集成测试)
    如果你想验证真实数据库的查询逻辑,那需要在测试前初始化数据库并插入测试数据,测试后清理数据。可以使用Prisma的测试数据库,配合beforeEach和afterEach钩子:
    beforeEach(async () => {
      // 插入测试数据
      await prisma.users.createMany({ data: usersMany });
    });
    
    afterEach(async () => {
      // 清理数据
      await prisma.users.deleteMany();
    });
    
    但注意这属于集成测试范畴,单元测试更推荐使用Mock隔离依赖,保证测试速度和稳定性。

内容的提问来源于stack exchange,提问作者AnonymousGeese

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 20:10:43