Nest.js e2e测试中如何为单个测试用例重写Provider实现
解决方案
你不需要重新构建测试模块或替换TestService实现,直接修改已注册mock repository的jest方法实现即可,步骤如下:
第一步:提取并保存mock的repository实例
在测试文件的全局作用域定义变量存储mock仓库,在beforeAll模块编译完成后获取实例:
// 测试文件全局作用域 let app: INestApplication; // 新增变量存储mock的TestEntity仓库 let mockTestRepo: jest.Mocked<Repository<TestEntity>>; beforeAll(async () => { const moduleRef = await Test.createTestingModule({ controllers: [TestController], providers: [ TestService, { provide: getRepositoryToken(TestEntity), useValue: { find: jest.fn(async () => testDatabaseResult), save: jest.fn(), }, }, ], }).compile(); // 新增:从模块容器中获取mock的repository实例 mockTestRepo = moduleRef.get(getRepositoryToken(TestEntity)) as jest.Mocked<Repository<TestEntity>>; app = moduleRef.createNestApplication(); app.use(cookieParser()); app.useGlobalPipes(new ValidationPipe()); await app.init(); });
第二步:在单个测试用例中修改find方法的mock实现
在你需要自定义返回结果的测试用例中,直接调用jest的mock方法修改返回值即可:
it('你的自定义测试用例', async () => { // 临时修改find方法的返回值 mockTestRepo.find.mockResolvedValue(otherMockedTestDatabaseResult); // 你的测试逻辑,此时TestService调用repository.find会拿到新的mock结果 const res = await request(app.getHttpServer()) .get('/test/xxx') .expect(200); // 可选:验证find方法被正确调用 expect(mockTestRepo.find).toHaveBeenCalledWith(/* 你期望的参数 */); // 可选:如果怕影响后续测试,可以重置mock到初始状态 mockTestRepo.find.mockResolvedValue(testDatabaseResult); });
可选:避免mock污染其他测试用例
如果你担心临时修改的mock值影响后续测试,可以在afterEach钩子中统一重置mock状态:
afterEach(() => { // 重置所有mock方法的调用记录和实现 jest.clearAllMocks(); // 恢复find方法的默认返回值 mockTestRepo.find.mockResolvedValue(testDatabaseResult); });
内容的提问来源于stack exchange,提问作者Furman
相关产品推荐
相关产品推荐

