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

NestJS Jest测试报错:无法读取undefined的'region'属性

NestJS Jest单元测试中ConfigService无法读取配置的解决方法

在NestJS项目中用Jest编写EmailService的单元测试时,遇到TypeError: Cannot read properties of undefined (reading 'region')错误。测试模块中注入了EmailService和ConfigService,但初始化时失败——EmailService构造函数中通过configService.get('aws')获取的配置为undefined,进而无法读取region属性。

报错代码示例

测试代码:

describe('EmailService', () => {
    let emailService: EmailService;
    let configService: ConfigService;

    beforeEach(async () => {
        const module: TestingModule = await Test.createTestingModule({
            providers: [EmailService, ConfigService],
        }).compile();

        emailService = module.get<EmailService>(EmailService);
        configService = module.get<ConfigService>(ConfigService);
    });

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

EmailService构造函数:

export class EmailService {
    private readonly config: IAwsConfig;
    private readonly region: IRegion;

    constructor(private readonly configService: ConfigService) {
        this.config = this.configService.get('aws');
        this.region = this.config.region;
    }
}

报错原因

直接在测试模块中声明ConfigService作为provider时,它没有像项目正常运行时那样通过ConfigModule完成初始化——无法加载环境变量或配置文件,导致configService.get('aws')返回undefined,后续访问this.config.region自然抛出错误。

解决方案

方法一:导入并配置ConfigModule(使用真实配置)

在测试模块中导入项目已配置的ConfigModule,让ConfigService能正确读取配置:

describe('EmailService', () => {
    let emailService: EmailService;

    beforeEach(async () => {
        const module: TestingModule = await Test.createTestingModule({
            imports: [
                ConfigModule.forRoot({
                    isGlobal: true,
                    envFilePath: '.env.test', // 可使用专门的测试环境配置文件
                }),
            ],
            providers: [EmailService],
        }).compile();

        emailService = module.get<EmailService>(EmailService);
    });

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

如果项目中ConfigModule已有全局注册或自定义配置(比如用load加载配置文件),直接导入现有模块即可:

imports: [ConfigModule],

方法二:Mock ConfigService(隔离测试,不依赖真实配置)

若不想依赖真实配置文件,可通过Jest模拟ConfigService的get方法,返回预设配置值:

describe('EmailService', () => {
    let emailService: EmailService;
    let mockConfigService: jest.Mocked<ConfigService>;

    beforeEach(async () => {
        mockConfigService = {
            get: jest.fn().mockImplementation((key: string) => {
                if (key === 'aws') {
                    return { region: 'us-east-1' }; // 返回预设的AWS配置
                }
                return null;
            }),
        } as jest.Mocked<ConfigService>;

        const module: TestingModule = await Test.createTestingModule({
            providers: [
                EmailService,
                {
                    provide: ConfigService,
                    useValue: mockConfigService,
                },
            ],
        }).compile();

        emailService = module.get<EmailService>(EmailService);
    });

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

    it('should fetch aws config from ConfigService', () => {
        expect(mockConfigService.get).toHaveBeenCalledWith('aws');
    });
});

这种方式更适合单元测试,能隔离外部依赖,无需加载真实环境变量,测试稳定性更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 03:02:03