본문 바로가기

내일배움캠프_개발일지/Node.js 기초

Node.js 심화 - 12

__________________________________________________

 

1-29  통합 테스트(Integration Test) 시작하기.

 

=>  < 3.5 테스트 코드 06 >

3.5 테스트 코드 Goal : 테스트 코드란 무엇인지 이해하고 Jest를 이용해 단위 테스트 코드를 작성할 수 있다.

 

 

폴더 : kimminsoo -> sparta -> node_js -> learning -> third_step -> layered-architecture-pattern

 

 

Supertest 시작하기.

=> supertest는 jest와 함께 사용하여 부분적인 테스트 뿐만 아니라,

원하는 요청(Request)를 이용해 반환(Response)된 정보를 검증하기 위해 사용 되는 대표적인 테스트 라이브러리.

 

supertest는 Express.js를 이용해 통합 테스트(Integration Test)를 구현할 수 있는 테스트 라이브러리.

Express의 서버를 구동시켜 가상의 API 요청(Request)을 보내고 원하는 결과가 발생 하였는지 검증할 수 있어.

 

supertest 라이브러리 하나만을 이용해 테스트 코드를 구현할 것이 아닌, 

jest와 supertest를 함께 사용해 더욱 명확하게 테스트 코드를 구현할 예정.

 

 

< supertest 예시 >

——

const supertest = require("supertest");

const app = require("../../app.js");

 

const response = await supertest(app)

  .post(`/api/posts`) // API의 HTTP Method & URL

  .query({}) // Request Query String

  .send({}) // Request Body

——

 

=> 

계층별 단위 테스트를 구현한 것과 다르게, supertest를 이용한 통합 테스트의 경우 Http Method, API의 URL을 입력하여 테스트를 진행.

 

supertest의 공식 예제는 메서드 체이닝(Method Chaning) 형식으로 테스트를 진행하지만, 

반환된 Response의 값을 기준으로도 테스트 코드를 작성할 수 있어.

 

 

 

— supertest의 문법 살펴보기 —

 

1)

.post(”URL”): Http Method와 URL을 입력해 테스트 하려는 API를 호출할 수 있습니다.

 

2)

.query(object): API에게 Query String을 이용해 데이터를 전달합니다.

 

3)

.send(object): API에게 Body에 데이터를 전달합니다.

 

4)

response: supertest를 이용해 API를 수행한 반환(response)값이 할당됩니다.

response.type: Response Header의 Content-type의 값입니다.

response.body: API Response의 반환된 json 데이터입니다.

response.headers: API Response에 반환된 헤더 정보입니다.

 

 

이 외에도 많은 문법들이 있어.

=> 참조 : https://github.com/ladjs/supertest#readme

 

 

 

 

 

________________________

 

— Sequelize Test DB 설정하기 —

 

=> 이걸 왜 설정해야 하는가?

통합 테스트를 구현 하면서, 만약에 우리가 서비스용 DB 와 테스트용 DB 를 분리하지 않았을 경우,

테스트 용으로 사용한 데이터들을 삭제하고자 하는 경우 우리가 테스트 때 사용했던 데이터들이 어떤 데이터인지

구분하지 못하게 될 가능성이 발생해.

 

테스트 용으로 CRUD 를 해봐야 할 텐데, 실제 서비스 중인 DB 로 그걸 실험할 순 없는 노릇 이잖아?

  따라서 테스트용 DB 를 따로 설정해야 해.

 

**************

Sequelize로 MySQL을 연결할 때, NODE_ENV를 test로 설정할 경우 기존에 설정된 DB가 아닌, 

config.json에 test 부분에 설정된 값으로 DB를 연결 할 수 있어.

 

통합 테스트(Integration Test)를 실행할 때, 기존에 사용하는 Development 환경이 아닌, 

test DB를 사용할 경우 데이터를 언제든지 자유롭게 관리 할 수 있고, 생성 및 삭제가 쉽게 가능.

 

 

 

1.

config/config.json 파일에서 test 환경을 원하는 DB 설정으로 수정하기.

 

——

"test": {

    "username": "root",

    "password": "lololo46",

    "database": "layered_architecture_pattern_test_db",

    "host": "express-database.cop97vlzzz2l.ap-northeast-2.rds.amazonaws.com",

    "dialect": "mysql"

  },

——

 

 

 

2.

config/config.json에 test 환경 설정을 완료하였을 경우 아래의 코드를 실행하여 DB와 Table을 생성.

 

——

# test 환경에 설정값을 이용해 DB를 생성.

NODE_ENV=test npx sequelize db:create

 

# test 환경에 설정값을 이용해 Table을 생성.

NODE_ENV=test npx sequelize db:migrate

——

 

 

 

 

3.

통합 테스트 (Integration Test) 를 구현하기에 앞서서 통합 테스트를 위한 설정을 셋팅해보자.

=> 

supertest 라이브러리를 사용하기 위해서는 express의 app 객체를 이용하여 테스트를 진행할 수 있어.

따라서, app.js 파일에서 express의 app 객체를 export 하여 테스트 코드에서 app 객체를 가져올 수 있도록 설정해야 해.

 

——

// app.js

 

const express = require('express')

const app = express()

const port = 4000

 

const router = require('./routes')

 

app.use(express.json())

app.use('/api', router)

 

app.listen(port, () => {

  console.log(port, '포트로 서버가 열렸어요!')

})

 

module.exports = app;

——

 

 

 

4.

supertest를 이용하여 생성(POST), 조회(GET)에 해당하는 API가 정상적으로 동작하는지를 확인할 예정.

통합 테스트를 구현하기 위해 __tests__/integration/ 폴더 하위에 posts.integration.spec.js 파일을 생성하자.

 

폴더 : kimminsoo -> sparta -> node_js -> learning -> third_step -> layered-architecture-pattern

파일 : __tests__/integration/posts.integration.spec.js

——

// __tests__/integration/posts.integration.spec.js

 

const supertest = require('supertest');

const app = require('../../app.js');

const { sequelize } = require('../../models/index.js');

 

// 통합 테스트(Integration Test)를 진행하기에 앞서 Sequelize에 연결된 모든 테이블의 데이터를 삭제합니다.

//  단, NODE_ENV가 test 환경으로 설정되어있는 경우에만 데이터를 삭제합니다.

beforeAll(async () => {

  if (process.env.NODE_ENV === 'test') await sequelize.sync();  

        // sync 는 정확히 말하자면 sequelize 가 초기화 될 때 DB에 필요한 테이블을 생성시켜주는 메소드. 

        // 현재 여기서는 테이블이 존재한다면 아무런 역할도 안하고, 존재하지 않는다면 model을 참조해서 테이블을 생성해.

  else throw new Error('NODE_ENV가 test 환경으로 설정되어 있지 않습니다.');

});

 

 

describe('Layered Architecture Pattern, Posts Domain Integration Test', () => {

 

  test('GET /api/posts API (getPosts) Integration Test Success Case, Not Found Posts Data', async () => {

    const response = await supertest(app)

      .get(`/api/posts`) // API의 HTTP Method & URL

      .query({}) // Request Query String

      .send({}) // Request Body

  });

 

  test('POST /api/posts API (createPost) Integration Test Success Case', async () => {

    // TODO: 여기에 코드를 작성해야합니다.

  });

 

  test('POST /api/posts API (createPost) Integration Test Error Case, Invalid Params Error', async () => {

    // TODO: 여기에 코드를 작성해야합니다.

  });

 

  test('GET /api/posts API (getPosts) Integration Test Success Case, is Exist Posts Data', async () => {

    // TODO: 여기에 코드를 작성해야합니다.

  });

});

 

 

afterAll(async () => {

  // 통합 테스트가 완료되었을 경우 sequelize의 연결된 테이블들의 정보를 초기화합니다.

  // sync({force: true})는 걍 초기화. 테이블을 생성하는데, 만약 이미 있다면 삭제하고 다시 생성.

  if (process.env.NODE_ENV === 'test') await sequelize.sync({ force: true });

  else throw new Error('NODE_ENV가 test 환경으로 설정되어 있지 않습니다.');

});

——

 

 

 

5.

services/posts.service.js 수정

——

  createPost = async (nickname, password, title, content) => {

    const createPostData = await this.postRepository.createPost(

      nickname,

      password,

      title,

      content

    );

 

    return {

      postId: createPostData.postId, <<<<==== 수정

      nickname: createPostData.nickname,

      title: createPostData.title,

      content: createPostData.content,

      createdAt: createPostData.createdAt,

      updatedAt: createPostData.updatedAt,

    };

  };

 

 ...

}

module.exports = PostService;

——

'내일배움캠프_개발일지 > Node.js 기초' 카테고리의 다른 글

Node.js 심화 - 14  (0) 2023.01.11
Node.js 심화 - 13  (0) 2023.01.09
Node.js 심화 - 11  (0) 2023.01.08
Node.js 심화 - 10  (0) 2023.01.06
Node.js 심화 - 9  (0) 2023.01.05