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

NestJS测试ConfigService时Mock不生效及自定义Fake类异常问题咨询

问题原因
  • 你在测试模块中同时导入了ConfigModule和自定义的ConfigService Mock,依赖注入出现冲突导致Mock没有实际生效
  • 你写的Mock的get方法没有匹配原生ConfigService.get的重载,没有处理第二个默认值参数,行为和原生实现不符
  • 自定义Fake类没有实现ConfigService的全量接口,导致类型校验报错,没有被正确注入
修复方案

1. 修复现有测试用例

你可以直接移除不需要的ConfigModule导入,同时修正get方法的Mock逻辑,修正后的测试代码如下:

import { Test, TestingModule } from '@nestjs/testing';
import { ConfigService } from '@nestjs/config';

describe('NestJS Configuration .env', () => {
    let service: ConfigService;

    beforeEach(async () => {
        const module: TestingModule = await Test.createTestingModule({
            providers: [
                {
                    provide: ConfigService,
                    useValue: {
                        get: jest.fn((key: string, defaultValue?: string) => {
                            if (key === 'FILES') {
                                return './fakedata/';
                            } else if (key === 'PORT') {
                                return '9999';
                            }
                            return defaultValue;
                        }),
                    },
                },
            ],
        }).compile();

        service = module.get<ConfigService>(ConfigService);
    });

    it('should be defined', () => {
        expect(service).toBeDefined();
    });

    it.each([
        ['FILES=', 'FILES', './', './fakedata/'],
        ['PORT=', 'PORT', '2000', '9999'],
        ['default value when key is not found', 'NOTFOUND', './', './'],
    ])('should get from the .env file, %s', (Text: string, Key: string, Default: string, Expected: string) => {
        const Result: string = service.get<string>(Key, Default);
        expect(Key).toBeDefined();
        expect(Result).toBe(Expected);
    });
});

如果你必须保留ConfigModule的导入,可以用overrideProvider方法明确覆盖原有实现:

const module: TestingModule = await Test.createTestingModule({
    imports: [ConfigModule.forRoot({ expandVariables: true })],
})
.overrideProvider(ConfigService)
.useValue({
    get: jest.fn((key: string, defaultValue?: string) => {
        if (key === 'FILES') return './fakedata/';
        if (key === 'PORT') return '9999';
        return defaultValue;
    })
})
.compile();

2. 修复可复用Fake类

让Fake类继承原生ConfigService,只重写你需要的get方法即可,既满足类型要求,也不需要实现所有无关方法:

import { ConfigService } from '@nestjs/config';

export class ConfigServiceFake extends ConfigService {
  override get(key: string, defaultValue?: unknown): unknown {
    switch (key) {
      case 'FILES':
        return './fakedata/';
      case 'PORT':
        return '9999';
      default:
        return defaultValue ?? null;
    }
  }
}

使用的时候直接通过useClass注入即可:

providers: [
  {
    provide: ConfigService,
    useClass: ConfigServiceFake
  }
]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 03:33:03