Вот моя текущая настройка:
Код: Выделить всё
jest.config.json
{
other configs...
"setupFilesAfterEnv": ["./test/jest.setup.ts"],
"globalSetup": "./test/mysql-global-setup.ts",
"globalTeardown": "./test/mysql-global-teardown.ts",
"maxWorkers": 1
}
Код: Выделить всё
// test/mysql-global-setup.ts
import { MySqlContainer, StartedMySqlContainer } from '@testcontainers/mysql';
import { initializeApp } from './test_nest_application';
const globalAny: any = global;
export default async () => {
// some mysql testcontainers settings...
console.log('Starting NestJS application...');
const testContext = await initializeApp();
console.log('NestJS application started.');
};
Код: Выделить всё
// test/test-nest-application.ts
import { Test } from '@nestjs/testing';
import { AppModule } from '../src/app.module';
import { WinstonLoggerService } from '../src/common/logger/logger.service';
import * as cookieParser from 'cookie-parser';
import { InternalExceptionsFilter } from '../src/common/filters/internal-exceptions.filter';
import { HttpExceptionsFilter } from '../src/common/filters/http-exception.filter';
import { INestApplication, ValidationPipe } from '@nestjs/common';
let app: INestApplication;
// declare global nest application
declare global {
var testContext;
}
export const initializeApp = async (): Promise => {
// use global.testContext as singleton instance
if (!global.testContext) {
const moduleFixture = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = moduleFixture.createNestApplication();
// setting some application's config values...
await app.init();
global.testContext = app;
}
return global.testContext;
};
Однако, согласно документу jest, сказано, что "Любые глобальные переменные, определенные через globalSetup может быть прочитан только в globalTeardown."
Чтобы обойти эту проблему, я определил одноэлементный модуль, который возвращает приложение Nest с именем InitializeApp() повторно использовать гнездо application.
Инициализированное приложение не определяется в globalSetup, оно определяется в отдельном модуле и добавляется в глобальную переменную.
В своих наборах тестов я использую такое приложение:
Код: Выделить всё
// test/rss/rss-e2e-spec.ts
describe('Rss Accept E2E Test', () => {
let app: INestApplication;
let rssRepository: Repository;
let rssAcceptRepository: Repository;
let redisService: RedisService;
beforeAll(async () => {
app = await initializeApp();
rssRepository = app.get(RssRepository);
rssAcceptRepository = app.get(RssAcceptRepository);
redisService = app.get(RedisService);
});
describe('POST /api/rss/accept/{rssId}', () => {
// test codes...
Код: Выделить всё
Nest could not find RssRepository element (this provider does not exist in the current context)
19 | beforeAll(async () => {
20 | app = await initializeApp();
> 21 | rssRepository = app.get(RssRepository);
| ^
22 | rssAcceptRepository = app.get(RssAcceptRepository);
23 | redisService = app.get(RedisService);
24 | });
Кроме того, если в метод .get() не передается значение, я получаю сообщение об ошибке, в котором говорится, что сам метод .get() не найден. Однако он продолжает говорить, что не может найти поставщиков.
Но инициализация гнездового приложения каждый раз с помощью beforeAll() работает нормально, без ошибок. (Это означает, что те же коды инициализации работали нормально, когда я запускал их в beforeAll().
Любые идеи или предложения о том, как правильно делиться экземпляром приложения Nest между наборы тестов были бы очень признательны.
Подробнее здесь: https://stackoverflow.com/questions/793 ... st-e2e-tes