如何在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
相关产品推荐
相关产品推荐

