NestJS 测试 ConfigService 工作

NestJS Testing ConfigService works

我正在编写一个应用程序来处理请求和 return 预定义响应,以允许通过当前无法写入内部测试的软件测试外部 REST 端点。因此,我的代码使用了 Nest JS 框架来处理路由,然后提取值和 returns 数据。 returned 数据存储在外部文件中。

为了处理不断变化和不同的团队使用情况,该程序使用 .env 文件提供要响应的文件所在的基(根)目录。我正在尝试编写一个测试用例以确保 NestJS ConfigService 正常工作,同时也用作我所有其他测试的基础。

不同的路由,需要return编辑不同的数据文件。我的代码需要模拟所有这些文件。由于此数据依赖于已读取 .env 的基本 ConfigService 来查找基本路径,因此我的路线基于此起点。

在开发过程中,我有一个设置了这些值的本地 .env 文件。但是,我想在不使用此 .env 文件的情况下进行测试,因此我的测试不依赖于 .env 文件的存在,因为 CI/CD 服务器、构建服务器等不会有 .env文件。

我只是尝试一个测试文件,然后使用配置,从我的模拟中获取设置数据。

nestjs-config.service.spec.ts

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

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

    beforeEach(async () => {
        const module: TestingModule = await Test.createTestingModule({
            imports: [
                ConfigModule.forRoot({
                    expandVariables: true,
                }),
            ],
            providers: [
                {
                    provide: ConfigService,
                    useValue: {
                        get: jest.fn((key: string) => {
                            if (key === 'FILES') {
                                return './fakedata/';
                            } else if (key === 'PORT') {
                                return '9999';
                            }
                            return null;
                        }),
                    },
                },
            ],
        }).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);
    });
});

这个测试中的问题是默认值总是 returned,这意味着 .env 文件没有被读取,但是提供者有代码来处理这个。

理想情况下,我想创建一个用于测试的假 class,这样我就可以在我所有的测试文件中使用它。但是,当尝试创建伪造的 class 时,我收到有关缺少其他方法的错误,这些方法与此 class.

无关
export class ConfigServiceFake {
    get(key: string) {
        switch (key) {
            case 'FILES':
                return './fakedata/';
            case 'PORT':
                return '9999';
        }
    }
}

这个好像没有执行,好像还是走原来的服务。

我能够对此进行调整,不需要外部引用,包括导入配置模块,使模拟更简单,并且不需要完整的定义。

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

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

    afterEach(() => {
        jest.clearAllMocks();
    });

    beforeEach(async () => {
        const FakeConfigService = {
            provide: ConfigService,
            useValue: {
                get: jest.fn((Key: string, DefaultValue: string) => {
                    switch (Key) {
                        case 'FILES':
                            return './fakedata/';
                            break;
                        case 'PORT':
                            return '9999';
                            break;
                        default:
                            return DefaultValue;
                    }
                }),
            },
        };

        const module: TestingModule = await Test.createTestingModule({
            providers: [FakeConfigService],
        }).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);
    });
});