Server/NodeJS & NestJS

NestJS) Jest TDD Setting

Juzdalua 2023. 1. 10. 10:52

TDD를 실행하려 yarn test 명령어를 실행했더니 아래와 같은 에러가 떴다.

please make sure that the argument connectionservice at index [0] is available in the roottestmodule context.

구글링을 하니 moduleNameMapper를 건드려야한다고 했다.

package.json과 tsconfig.ts 파일을 수정했지만 또 다른 문제가 발생하여($1) 두 파일은 건들지 않기로 했다.

 

아래와 같은 방법으로 해결했다.

 

1. 절대경로를 상대경로로 바꿔준다.(Change Relative Path to Absolute Path)

// user.controller.spec.ts

// src/user/user.controller 자동 임포트 변경
./user.controller

 

2. Module파일과 동일하게 spec 파일을 맞춰준다.

에러를 확인하면 몇 번째 인덱스를 찾을 수 없다고 보여준다.

 

// user.mnodule.ts

@Module({
  imports: [
    AuthModule
  ],
  controllers: [UserController],
  providers: [
    UserService,
    ConnectionService,
    SignService,
    RMQService,
  ]
})
export class UserModule { }

 

만약 위와 같이 모듈이 설정되어있다면 해당 spec파일에 다음과 같이 코드를 추가한다.

// user.controller.spec.ts

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

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      controllers: [UserController],
      providers: [UserService, ConnectionService, SignService, RMQService],
    }).compile();

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

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

});

beforeEach 함수 내부에 controllers, providers에 미리 작성된 모듈과 동일하게 작성해주면 된다.

 

이제 jest가 정상적으로 작동된다.

test코드가 정상적으로 작동되는지 description을 보고 싶다면 아래와 같이 명령어로 실행한다.

# yarn test --help
yarn test:watch --verbose

 

 

추가 셋팅)

1. spec 파일에서 .env 읽어오기

// package.json

{
    ...,
    "jest": {
    	...,
        "setupFiles": [
        	"dotenv/config"
        ]
    }
}

 

2. DTO data 맞추기

ex) @IsEmail() dto value

// ~.controller.spec.ts

import { Test, TestingModule } from '@nestjs/testing';
import { plainToInstance } from 'class-transformer';
import { SignController } from './sign.controller';
import { SignService } from './sign.service';
import { validate, ValidationError } from 'class-validator';
import { CreateSignEmailCheckDto } from './dto/create-sign.dto';

describe('SignController', () => {
  let controller: SignController;
  
  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      controllers: [SignController],
      providers: [SignService],
    }).compile();
  
    controller = module.get<SignController>(SignController);
  });

  it('should be error of POST email/check', async () => {
    const invalidEmail = {email: 'abc'};

    const result = plainToInstance(CreateSignEmailCheckDto, invalidEmail);
    const error: ValidationError[] = await validate(result);
    expect(error.length).not.toEqual(0);
    expect(error[0].constraints.isEmail).toContain('email must be an email');
  });
}