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

如何在Jest单元测试中适配bcrypt加密以测试FindAll()方法

调整NestJS用户查询测试用例(适配bcrypt加密密码)

针对密码加密导致测试断言失败的问题,提供三种实用调整方案:

方案1:Mock Prisma服务,返回预设哈希密码

单元测试应隔离外部依赖,直接mock Prisma的查询方法,返回带有预先生成哈希密码的用户数据,避免依赖实际加密逻辑或数据库。

示例代码:

// 在测试模块初始化时mock PrismaService
const module: TestingModule = await Test.createTestingModule({
  providers: [
    UsersService,
    {
      provide: PrismaService,
      useValue: {
        users: {
          findMany: jest.fn().mockResolvedValue([
            {
              username: 'user1',
              name: 'User One',
              password: '$2b$10$Z8HxQaoxeQ7V7kLzW5sKqOvXrTtY.uB9eFgHjKlMnOpQrStUvWxYz', // 预先生成的bcrypt哈希值
              email: 'user1@test.com',
              tasks: [],
            },
            {
              username: 'user2',
              name: 'User Two',
              password: '$2b$10$AbCdEfGhIjKlMnOpQrStUvWxYzZaBcDeFgHiJkLmNoPqRsTuVwX',
              email: 'user2@test.com',
              tasks: [],
            },
          ]),
        },
      },
    },
  ],
}).compile();

const service = module.get<UsersService>(UsersService);
const prisma = module.get<PrismaService>(PrismaService);

// 测试用例
describe('findAll', () => {
  it('should return all users with hashed passwords', async () => {
    const result = await service.findAll();
    expect(prisma.users.findMany).toHaveBeenCalled();
    // 可直接匹配预设哈希数据,或只验证非密码字段
    expect(result.map(u => ({ username: u.username, name: u.name, email: u.email })))
      .toEqual(usersMany.map(u => ({ username: u.username, name: u.name, email: u.email })));
  });
});

方案2:集成测试场景:预先生成加密密码存入测试库

如果是需要连接测试数据库的集成测试,可在测试前用bcrypt加密明文密码,插入数据库后再断言返回的哈希值有效性。

示例代码:

import * as bcrypt from 'bcrypt';

describe('findAll', () => {
  beforeEach(async () => {
    // 加密明文密码
    const hashedPwd1 = await bcrypt.hash('123', 10);
    const hashedPwd2 = await bcrypt.hash('456', 10);
    // 插入测试数据
    await prisma.users.createMany({
      data: [
        { ...usersMany[0], password: hashedPwd1 },
        { ...usersMany[1], password: hashedPwd2 },
      ],
    });
  });

  afterEach(async () => {
    // 清理测试数据
    await prisma.users.deleteMany();
  });

  it('should return users with valid hashed passwords', async () => {
    const result = await service.findAll();
    // 验证哈希密码可匹配原明文
    expect(await bcrypt.compare('123', result[0].password)).toBe(true);
    expect(await bcrypt.compare('456', result[1].password)).toBe(true);
    // 验证其他字段正确性
    expect(result[0].username).toBe(usersMany[0].username);
    expect(result[1].email).toBe(usersMany[1].email);
  });
});

方案3:断言时忽略密码字段

如果测试重点是验证用户列表的基本信息,无需关注密码具体值,可直接排除密码字段后对比。

示例代码:

describe('findAll', () => {
  it('should return all users (ignore password field)', async () => {
    const result = await service.findAll();
    // 移除密码字段后对比
    const cleanResult = result.map(({ password, ...rest }) => rest);
    const cleanExpected = usersMany.map(({ password, ...rest }) => rest);
    expect(cleanResult).toEqual(cleanExpected);
  });
});

内容的提问来源于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 09:10:35