Основные поставщики в тестах NestJS Jest - PullRequest
0 голосов
/ 30 августа 2018

Я хочу использовать экземпляр Mongo в памяти для макетирования данных в целях тестирования в моем приложении NestJS. У меня есть поставщик базы данных, который подключается к моей производственной базе данных с помощью mongoose, который является частью моего модуля базы данных, который, в свою очередь, импортируется в другие модули.

Я пытаюсь переопределить поставщика базы данных в моих тестах Jest, чтобы я мог использовать экземпляр Mongo в памяти.

Это модуль базы данных:

import { Module } from '@nestjs/common';
import { databaseProviders } from './database.providers';

@Module({
  providers: [...databaseProviders],
  exports: [...databaseProviders],
})
export class DatabaseModule { }

и база данных Provider:

export const databaseProviders = [
  {
    provide: 'DbConnectionToken',
    useFactory: async (): Promise<typeof mongoose> =>
      await mongoose.connect(PRODUCTION_DATABASE_URL),
  },
];

У меня есть модуль Events, который импортирует и использует соединение с базой данных из модуля базы данных. Служба Events - это то, что я тестирую - beforeEach в моих events.spec.ts:

beforeEach(async () => {
    const module = await Test.createTestingModule({
      imports: [EventsModule],
      providers: [
        EventsService,
        {
          provide: 'EventModelToken',
          useValue: EventSchema
        },
      ],
    }).compile();

    eventService = module.get<EventsService>(EventsService);
  });

Я попытался импортировать модуль DatabaseModule в модуль тестирования, а затем добавить своего собственного провайдера, предполагая, что он переопределит провайдера базы данных, но он не работает, как я ожидал, поэтому я боюсь, что я могу неправильно понять, как переопределяющие провайдеры работают в этом контексте.

Вот что я пытался:

beforeEach(async () => {
  const module = await Test.createTestingModule({
    imports: [EventsModule, DatabaseModule],
    providers: [
      EventsService,
      {
        provide: 'EventModelToken',
        useValue: EventSchema
      },
      {
        provide: 'DbConnectionToken',
        useFactory: async (): Promise<typeof mongoose> =>
          await mongoose.connect(IN_MEMORY_DB_URI),
      },
    ],
  }).compile();

  eventService = module.get<EventsService>(EventsService);
});

1 Ответ

0 голосов
/ 07 сентября 2018

Как указано в документе https://docs.nestjs.com/fundamentals/unit-testing, вы можете переопределить провайдера значением, фабрикой или классом.

beforeEach(async () => {
    const module = await Test.createTestingModule({
        imports: [EventsModule, DatabaseModule],
        providers: [
            EventsService,
        ],
    }).overrideProvider('DbConnectionToken')
    .useFactory({
        factory: async (): Promise<typeof mongoose> =>
          await mongoose.connect(IN_MEMORY_DB_URI),
    })
    .compile();

    eventService = module.get<EventsService>(EventsService);
});

Альтернативой может быть создание провайдера для ваших конфигов :) Вот так!

@Module({})
export DatabaseModule {
    public static forRoot(options: DatabaseOptions): DynamicModule {
        return {
            providers: [
                {
                    provide: 'DB_OPTIONS',
                    useValue: options,
                },
                {
                    provide: 'DbConnectionToken',
                    useFactory: async (options): Promise<typeof mongoose> => await mongoose.connect(options),
                    inject: ['DB_OPTIONS']
                },
            ],
        };
    }
}

Тогда используйте вот так

const module: TestingModule = await Test.createTestingModule({
    imports: [DatabaseModule.forRoot({ host: 'whatever'})],
});

Теперь вы можете изменять параметры, где бы вы их не использовали :)

...