NestJS 및 비동기 기능을 사용한 Jest

Aug 18 2020

나는 시험에의 비동기 기능을 시도하고 servicenestJS .

이 함수는 비동기 적입니다 ... 기본적으로 데이터베이스 (저장소-TypeORM 사용)에서 값 (JSON)을 가져오고 데이터를 성공적으로 가져 오면 다른 클래스 (DTO)로 "변환"합니다. 구현 :

async getAppConfig(): Promise<ConfigAppDto> {
  return this.configRepository.findOne({
    key: Equal("APPLICATION"),
  }).then(config => {
    if (config == null) {
      return new class implements ConfigAppDto {
        clientId = '';
        clientSecret = '';
      };
    }
    return JSON.parse(config.value) as ConfigAppDto;
  });
}

컨트롤러를 사용하여 이것이 잘 작동하는지 확인했습니다. 이제 Jest를 사용하여 테스트를 수행하려고하지만 성공하지 못했습니다. 내 문제는 .. 에서 findOne함수 를 조롱하는 방법 입니다 repository.

편집 : 나는 @golevelup/nestjs-testing조롱 하는 데 사용하려고합니다 Repository!

나는 이미를 조롱 repository했지만 어떤 이유로 resolve..

describe('getAppConfig', () => {
  const repo = createMock<Repository<Config>>();

  beforeEach(async () => {
    await Test.createTestingModule({
      providers: [
        ConfigService,
        {
          provide: getRepositoryToken(Config),
          useValue: repo,
        }
      ],
    }).compile();
  });

  it('should return ConfigApp parameters', async () => {
    const mockedConfig = new Config('APPLICATION', '{"clientId": "foo","clientSecret": "bar"}');
    repo.findOne.mockResolvedValue(mockedConfig);
    expect(await repo.findOne()).toEqual(mockedConfig); // ok

    const expectedReturn = new class implements ConfigAppDto {
      clientId = 'foo';
      clientSecret = 'bar';
    };
    expect(await service.getAppConfig()).toEqual(expectedReturn);

    // jest documentation about async -> https://jestjs.io/docs/en/asynchronous
    // return expect(service.getAppConfig()).resolves.toBe(expectedReturn);
  });
})
  • expect(await repo.findOne()).toEqual(mockedConfig);좋은 작품;
  • expect(await service.getAppConfig()).toEqual(expectedReturn);시간 초과가 있습니다 => Async callback was not invoked within the 5000 ms timeout specified by jest.setTimeout;

디버그를 사용하여, 나는이 것을 볼 service.getAppConfig(),라고 repository.findOne()도 있지만 .thenfindOne의의 저장소는 호출되지 않습니다.

업데이트 :을 사용하여 저장소를 모의하려고하는데 @golevelup/nestjs-testing어떤 이유로 모의 결과가 서비스에서 작동하지 않습니다. jest아래 코드와 같이 (아래 코드와 같이) 만 사용하여 저장소를 조롱하면 테스트가 작동하므로 실제 문제는 @golevelup/nestjs-testing.

...
provide: getRepositoryToken(Config),
useValue: {
  find: jest.fn().mockResolvedValue([new Config()])
},
...

답변

2 RobertoCorreia Aug 21 2020 at 22:25

그래서 내 진짜 문제는 내가 어떻게 조롱하는지 Repository입니다 NestJS. 어떤 이유로를 사용하여 조롱하면 @golevelup/nestjs-testing이상한 일이 발생합니다!

에서 이것에 대한 좋은 문서를 찾지 못해서 @golevelup/nestjs-testing사용을 포기했습니다.

질문에 대한 내 솔루션은 사용하는 것이었다 JestNestJS기능 ... 결과 코드했다 :

서비스 :

// i'm injecting Connection because I need for some transactions later;
constructor(@InjectRepository(Config) private readonly configRepo: Repository<Config>, private connection: Connection) {}

async getAppConfig(): Promise<ConfigApp> {
  return this.configRepo.findOne({
    key: Equal("APPLICATION"),
  }).then(config => {
    if (config == null) {
      return new ConfigApp();
    }
    return JSON.parse(config.value) as ConfigApp;
  })
}

테스트 :

describe('getAppConfig', () => {
  const configApi = new Config();
  configApi.key = 'APPLICATION';
  configApi.value = '{"clientId": "foo", "clientSecret": "bar"}';

  beforeEach(async () => {
    const module = await Test.createTestingModule({
      providers: [
        ConfigAppService,
        {
          provide: getRepositoryToken(Config),
          useValue: {
            findOne: jest.fn().mockResolvedValue(new
            Config("APPLICATION", '{"clientId": "foo", "clientSecret": "bar"}')),
          },
        },
        {
          provide: getConnectionToken(),
          useValue: {},
        }
      ],
    }).compile();

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

  it('should return ConfigApp parameters', async () => {
    const expectedValue: ConfigApp = new ConfigApp("foo", "bar");

    return service.getAppConfig().then(value => {
      expect(value).toEqual(expectedValue);
    })
  });
})

이 솔루션에 사용 된 몇 가지 소스 : https://github.com/jmcdo29/testing-nestjs/tree/master/apps/typeorm-sample

1 Leo Aug 18 2020 at 19:53

expect(await repo.findOne()).toEqual(mockedConfig);조롱했기 때문에 효과가 있다고 생각 하므로 즉시 반환됩니다. 의 경우 expect(await service.getAppConfig()).toEqual(expectedReturn);조롱하지 않았으므로 시간이 더 걸릴 수 있으므로 it함수가 Promise완전히 해결 되기 전에 반환 됩니다.

jest 문서에서 게시 한 댓글은 getAppConfig().

service.getAppConfig = jest.fn(() => Promise.resolve(someFakeValue))

또는

spyOn(service, 'getAppConfig').and.mockReturnValue(Promise.resolve(fakeValue))