728x90

오늘 설명은 Controller 기반의 테스트에서 다음 내용입니다.

  1. Repository 객체를 Mock으로 주입
  2. Connection 객체를 Mock으로 주입
  3. mockAuthGuard 객체를 Mock으로 주입하여 로그인 처리
  4. 첨부파일 업로드

Mock 객체 생성

자동으로 만들어진 테스트 케이스는 아래와 같습니다

import { Test, TestingModule } from '@nestjs/testing';
import { Controller } from './my.controller';

describe('Controller', () => {
  let controller: Controller;

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

    controller = module.get<Controller>(Controller);
  });

  it('should be defined', () => {
    expect(controller).toBeDefined();
  });
});

Controller의 소스는 기본적으로 service를 호출하고, service에서는 Entity를 이용하여 Repository를 Inject 합니다.

Inject에 필요한 Mock객체들을 생성을 합니다.
내부 구현이 필요 없을 경우 jest.fn()를 활용하면 쉽게 처리 할 수 있습니다.

class MockRepository {

  async save(any) {
    return new OssAtachFileDEntity({
      "refSeq": 1,
      "refCd": "RE",
      "regrId": "12345",
      "modrId": "12345",
      "fileName": "첨부파일 테스트.pdf",
      "filePath": "202106/e55daf47-af60-4e8d-9e54-67cbfc680556",
      "size": 73666,
      "fileExtension": "pdf",
      "seq": 2
    });
  }
  async find() {
    return [new OssAtachFileDEntity({
      "refSeq": 1,
      "refCd": "RE",
      "regrId": "12345",
      "modrId": "12345",
      "fileName": "첨부파일 테스트.pdf",
      "filePath": "202106/e55daf47-af60-4e8d-9e54-67cbfc680556",
      "size": 73666,
      "fileExtension": "pdf",
      "seq": 2
    })];
  }
  async findOne(any) {
    return new OssAtachFileDEntity({
      "refSeq": 1,
      "refCd": "RE",
      "regrId": "12345",
      "modrId": "12345",
      "fileName": "첨부파일 테스트.pdf",
      "filePath": "202106/e55daf47-af60-4e8d-9e54-67cbfc680556",
      "size": 73666,
      "fileExtension": "pdf",
      "seq": 2
    });
  }

  async remove() {

  }
}

const mockConnection = () => ({
  transaction: jest.fn(),
  createQueryRunner: () => ({
    connect: jest.fn(),
    startTransaction: jest.fn(),
    commitTransaction: jest.fn(),
    rollbackTransaction: jest.fn(),
    release: jest.fn(),
    manager: {
      save: (r => r)
    }
  })
});

const mockAuthGuard: CanActivate = {
  canActivate: (context: ExecutionContext) => {
    const request = context.switchToHttp().getRequest();
    request.user = {
      id: '12345',
      name: "임광규",
      email: 'lahuman@daum.net'
    };
    return request.user;
  }
};

Mock 객체 주입

구현한 Mock 객체들을 module에 Inject 처리를 합니다.

 let app: INestApplication;
  let httpService: HttpService;
  let controller: Controller;

  beforeEach(async () => {

    const module: TestingModule = await Test.createTestingModule({
      imports: [HttpModule, ConfigModule.forRoot({ isGlobal: true })],
      controllers: [Controller],
      providers: [Service,
        {
          provide: getRepositoryToken(OssReqMEntity),
          useClass: MockRepository,
        },
        {
          provide: Connection,
          useFactory: mockConnection
        }
      ],
    })
      .overrideGuard(AuthenticatedGuard).useValue(mockAuthGuard)
      .compile();
    app = module.createNestApplication();
    httpService = module.get<HttpService>(HttpService);
    await app.init();

    controller = module.get<Controller>(Controller);
  });

첨부파일 테스트

 it('첨부파일 추가', async () => {
    const response = await request(app.getHttpServer())
      .post("/attach-file/upload")
      .attach('file', '/path/file-name')
      .expect(201);
    expect(JSON.parse(response.text).status).toEqual(true);
  });

로그인 처리 테스트

로그인의 경우 PASSPORT-SAML 방식을 이용하였으며 Request에 user라는 객체를 이용합니다.

등록된 결과에 userId가 12345인지 확인하는 테스트를 진행합니다.

 it('조회', async () => {
    const response = await request(app.getHttpServer())
      .get('/1')
      .expect(200);
    expect(JSON.parse(response.text).regrId).toEqual("12345");
  });

이상으로 기본적인 Nestjs 테스트 케이스를 사용해보았습니다.

은근 어려웠네요.

Posted by lahuman

댓글을 달아 주세요