Testing

Testing

자동 테스트는 모든 기능을 갖춘 소프트웨어 제품의 필수 부분입니다. 시스템의 가장 민감한 부분을 다루는 것이 매우 중요합니다. 이러한 목표를 달성하기 위해 통합 테스트, 단위 테스트, e2e 테스트 등과 같은 다양한 테스트 세트를 생성합니다. 그리고 Nest는 테스트 경험을 향상시키는 다양한 테스트 유틸리티를 제공합니다.

일반적으로, 당신은 테스팅 프레임 워크를 사용할 수 있습니다. 툴링을 시행하지 않으며 요구 사항에 맞는 것을 선택하십시오. 기본 Nest 애플리케이션 스타터는 Jest 프레임 워크와 통합되어 테스트 작성을 시작할 때 발생하는 오버 헤드를 줄이지만 여전히 제거할 수 있습니다. 다른 도구를 쉽게 사용하십시오.

Installation

먼저 필요한 패키지를 설치해야합니다.

$ npm i --save-dev @nestjs/testing

Unit testing

다음 예제에서는 각각 CatsControllerCatsService라는 두 가지 클래스가 있습니다. 앞에서 언급했듯이 Jest는 본격적인 테스트 프레임 워크로 사용됩니다. 이 프레임 워크는 테스트 실행기처럼 작동하며, 모의, 감시 등을 돕는 assert 함수 및 test-doubles 유틸리티를 제공합니다. 일단 호출 된 result변수를 반환하도록catsService.findAll()메소드를 수동으로 적용했습니다. 덕분에 catsController.findAll()이 예상 결과를 반환하는지 테스트할 수 있습니다.

@@filename(cats.controller.spec)
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

describe('CatsController', () => {
  let catsController: CatsController;
  let catsService: CatsService;

  beforeEach(() => {
    catsService = new CatsService();
    catsController = new CatsController(catsService);
  });

  describe('findAll', () => {
    it('should return an array of cats', async () => {
      const result = ['test'];
      jest.spyOn(catsService, 'findAll').mockImplementation(() => result);

      expect(await catsController.findAll()).toBe(result);
    });
  });
});
@@switch
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

describe('CatsController', () => {
  let catsController;
  let catsService;

  beforeEach(() => {
    catsService = new CatsService();
    catsController = new CatsController(catsService);
  });

  describe('findAll', () => {
    it('should return an array of cats', async () => {
      const result = ['test'];
      jest.spyOn(catsService, 'findAll').mockImplementation(() => result);

      expect(await catsController.findAll()).toBe(result);
    });
  });
});

info 힌트 테스트 파일은 테스트된 클래스 근처에 보관하십시오. 테스트 파일에는 .spec 또는 .test 접미사가 있어야합니다.

우리는 지금까지 기존 Nest 테스트 유틸리티를 사용하지 않았습니다. 테스트 한 클래스의 인스턴스화를 수동으로 처리 했으므로 위의 테스트 스위트는 Nest와 관련이 없습니다. 이러한 유형의 테스트를 isolated 테스트라고합니다.

Testing utilities

@nestjs/testing 패키지는 테스트 프로세스를 향상시키는 유틸리티 세트를 제공합니다. 노출 된Test 클래스를 사용하여 이전 예제를 다시 작성해 봅시다.

@@filename(cats.controller.spec)
import { Test } from '@nestjs/testing';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

describe('CatsController', () => {
  let catsController: CatsController;
  let catsService: CatsService;

  beforeEach(async () => {
    const module = await Test.createTestingModule({
        controllers: [CatsController],
        providers: [CatsService],
      }).compile();

    catsService = module.get<CatsService>(CatsService);
    catsController = module.get<CatsController>(CatsController);
  });

  describe('findAll', () => {
    it('should return an array of cats', async () => {
      const result = ['test'];
      jest.spyOn(catsService, 'findAll').mockImplementation(() => result);

      expect(await catsController.findAll()).toBe(result);
    });
  });
});
@@switch
import { Test } from '@nestjs/testing';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

describe('CatsController', () => {
  let catsController;
  let catsService;

  beforeEach(async () => {
    const module = await Test.createTestingModule({
        controllers: [CatsController],
        providers: [CatsService],
      }).compile();

    catsService = module.get(CatsService);
    catsController = module.get(CatsController);
  });

  describe('findAll', () => {
    it('should return an array of cats', async () => {
      const result = ['test'];
      jest.spyOn(catsService, 'findAll').mockImplementation(() => result);

      expect(await catsController.findAll()).toBe(result);
    });
  });
});

Test 클래스에는 모듈 메타 데이터 ( @Module) 데코레이터에 전달된 것과 동일한 객체)를 인수로 취하는createTestingModule()메소드가 있습니다. 이 메소드는 TestingModule 인스턴스를 만들어 몇 개의 메소드를 제공하지만 단위 테스트와 관련하여 컴파일 중 하나 인 compile()만 유용합니다. 이 기능은 비동기이므로 기다려야합니다. 모듈이 컴파일되면, get() 메소드를 사용하여 모든 인스턴스를 검색 할 수 있습니다.

실제 인스턴스를 모방하기 위해 custom provider로 기존 공급자를 재정의 할 수 있습니다.

End-to-end testing

애플리케이션이 커지면 각 API 엔드 포인트의 동작을 수동으로 테스트하기가 어렵습니다. 엔드 투 엔드 테스트는 모든 것이 올바르게 작동하고 프로젝트 요구 사항에 맞는지 확인하는 데 도움이됩니다. e2e 테스트를 수행하기 위해 unit testing의 경우와 동일한 구성을 사용하지만 HTTP 요청을 시뮬레이션 할 수있는 supertest 라이브러리를 활용합니다. .

@@filename(cats.e2e-spec)
import * as request from 'supertest';
import { Test } from '@nestjs/testing';
import { CatsModule } from '../../src/cats/cats.module';
import { CatsService } from '../../src/cats/cats.service';
import { INestApplication } from '@nestjs/common';

describe('Cats', () => {
  let app: INestApplication;
  let catsService = { findAll: () => ['test'] };

  beforeAll(async () => {
    const module = await Test.createTestingModule({
      imports: [CatsModule],
    })
      .overrideProvider(CatsService)
      .useValue(catsService)
      .compile();

    app = module.createNestApplication();
    await app.init();
  });

  it(`/GET cats`, () => {
    return request(app.getHttpServer())
      .get('/cats')
      .expect(200)
      .expect({
        data: catsService.findAll(),
      });
  });

  afterAll(async () => {
    await app.close();
  });
});
@@switch
import * as request from 'supertest';
import { Test } from '@nestjs/testing';
import { CatsModule } from '../../src/cats/cats.module';
import { CatsService } from '../../src/cats/cats.service';
import { INestApplication } from '@nestjs/common';

describe('Cats', () => {
  let app: INestApplication;
  let catsService = { findAll: () => ['test'] };

  beforeAll(async () => {
    const module = await Test.createTestingModule({
      imports: [CatsModule],
    })
      .overrideProvider(CatsService)
      .useValue(catsService)
      .compile();

    app = module.createNestApplication();
    await app.init();
  });

  it(`/GET cats`, () => {
    return request(app.getHttpServer())
      .get('/cats')
      .expect(200)
      .expect({
        data: catsService.findAll(),
      });
  });

  afterAll(async () => {
    await app.close();
  });
});

info 힌트 e2e 테스트 파일을 e2e 디렉토리 안에 보관하십시오. 테스트 파일에는 .e2e-spec 또는 .e2e-test 접미사가 있어야합니다.

cats.e2e-spec.ts 테스트 파일은 단일 HTTP 엔드 포인트 테스트 (/cats)를 포함합니다. 우리는app.getHttpServer()메소드를 사용하여 Nest 애플리케이션의 백그라운드에서 실행되는 기본 HTTP 서버를 선택했습니다. TestingModule 인스턴스는 overrideProvider()메소드를 제공하므로 가져온 모듈에 의해 선언 된 기존 제공자를 오버라이드 할 수 있습니다. 또한 해당 메소드 인 overrideGuard(), overrideInterceptor (), overrideFilter()overridePipe()를 각각 사용하여 가드, 인터셉터, 필터 및 파이프를 연속적으로 대체 할 수 있습니다.

컴파일된 모듈에는 다음 표에 잘 설명 된 여러 가지 방법이 있습니다.

Last updated