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

如何在NestJS的Jest E2E测试中注入服务获取验证码?

在NestJS E2E测试中获取短信验证码的可行方案

当然可以在app.e2e-spec.ts中注入服务来查询验证码,你之前直接用Mongoose连接失败,大概率是测试环境的数据库隔离或者实例获取方式不对。下面是几种靠谱的实现方式:


1. 注入业务服务直接查询

通过NestJS的测试模块,直接导入包含验证码逻辑的模块,获取对应的服务实例来查询验证码,这是最贴合业务逻辑的方式:

import { Test } from '@nestjs/testing';
import { INestApplication } from '@nestjs/common';
import { AuthService } from '../src/auth/auth.service';
import * as request from 'supertest';

describe('Auth E2E', () => {
  let app: INestApplication;
  let authService: AuthService;

  beforeAll(async () => {
    const moduleFixture = await Test.createTestingModule({
      imports: [AppModule], // 导入你的主模块或验证码所在模块
    }).compile();

    app = moduleFixture.createNestApplication();
    await app.init();
    authService = moduleFixture.get(AuthService); // 注入目标服务
  });

  it('should login with valid SMS code', async () => {
    // 1. 触发发送验证码接口
    await request(app.getHttpServer())
      .post('/auth/send-sms')
      .send({ phone: '13800138000' })
      .expect(200);

    // 2. 通过注入的服务获取验证码
    const smsCode = await authService.getLatestSmsCode('13800138000'); // 假设你有这个查询方法

    // 3. 使用验证码完成登录
    await request(app.getHttpServer())
      .post('/auth/login')
      .send({ phone: '13800138000', code: smsCode })
      .expect(201);
  });

  afterAll(async () => {
    await app.close();
  });
});

2. 直接操作Mongoose模型(修复之前的问题)

如果想直接查数据库,要通过NestJS的测试模块注入Mongoose模型,而不是自己单独建立连接:

import { getModelToken } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { SmsCode } from '../src/sms/sms-code.schema'; // 你的验证码Schema

// 在beforeAll中获取模型实例
const smsCodeModel: Model<SmsCode> = moduleFixture.get(getModelToken(SmsCode.name));

// 在测试用例中查询最新验证码
it('should login with valid SMS code', async () => {
  // 先触发发送验证码...

  const latestCodeDoc = await smsCodeModel.findOne({ phone: '13800138000' }).sort({ createdAt: -1 });
  const smsCode = latestCodeDoc?.code;

  // 用验证码登录...
});

注意:测试时一定要用独立的测试数据库,并且每个测试用例执行后清理验证码数据,避免用例间互相干扰。


3. 替换短信服务为模拟实现(更轻量)

如果不想依赖数据库,可以在测试环境中把真实的短信服务替换成模拟类,让它直接存储验证码,方便测试时获取:

// 定义模拟短信服务
class MockSmsService {
  private storedCodes: Record<string, string> = {};

  sendSms(phone: string, code: string) {
    this.storedCodes[phone] = code;
    return Promise.resolve();
  }

  getStoredCode(phone: string) {
    return this.storedCodes[phone];
  }
}

// 在测试模块中替换服务
const moduleFixture = await Test.createTestingModule({
  imports: [AuthModule],
  providers: [
    {
      provide: SmsService, // 替换真实的短信服务令牌
      useClass: MockSmsService,
    },
  ],
}).compile();

// 在测试用例中获取模拟服务
const mockSmsService = moduleFixture.get(SmsService) as MockSmsService;

// 触发发送验证码后直接获取
const smsCode = mockSmsService.getStoredCode('13800138000');

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 20:52:11