본문 바로가기
개발자 도전기/[STUDY] TEST CODE

TDD | node.js | 사용자 목록 조회 API 테스트 코드 만들기

by 답수 2022. 5. 23.
728x90
반응형

 

 

※ 인프런 - 테스트주도개발(TDD)로 만드는 NodeJS API 서버 강의를 기반으로 정리한 내용입니다.

 

 

앞에서 간단하게 구현해봤던 /users API를 구체적으로 작성해볼 것이다.

 

GET /users 는 성공했을 때, 다음과 같은 결과가 도출된다.

  • 유저 객체를 담은 배열로 응답
  • 최대 limit 갯수만큼 응답

실패 했을 때는 다음과 같은 결과가 나오게 할 것이다.

  • limit이 숫자형이 아니면 400 응답
  • offset이 숫자형이 아니면 400 응답

limit은 응답 받을 데이터의 총 길이, offset은 응답 받은 데이터 중 스킵할 때, 그 길이의 차이를 나타내는 파라미터

 

index.spec.js의 파일을 다음과 같이 수정한다.

const app = require('./index');
const request = require('supertest');

describe('GET /users는 ', () => {
    describe('성공 시', () => {
        it('유저 객체를 담은 배열로 응답한다', (done) => {
            request(app)
                .get('/users')
                .end((err, res) => {
                    res.body.should.be.instanceOf(Array);
                    done();
                });
        });
    });
});

res.body.should.be.instanceOf()에서 instanceOf(A) 메소드는 해당 메소드의 인스턴스가 A 생성자인지 판단하는 기능을 한다. 즉 응답 받은 데이터의 body가 배열인지 아닌지를 알기 위한 방법이다.

 

그럼 테스트를 한 번 돌려 보자.

.\node_modules\.bin\mocha .\index.spec.js

 

 

위와 같은 에러는 be 라는 요소를 찾을 수 없다는 것으로, should 모듈을 불러오는 것을 깜빡했기 때문에 발생한 것.. should 추가 후 다시 테스트

const app = require('./index');
const request = require('supertest');
const should = require('should');

describe('GET /users는 ', () => {
    describe('성공 시', () => {
        it('유저 객체를 담은 배열로 응답한다', (done) => {  
        // it의 콜백함수로 done()을 사용하면 자동으로 비동기 테스트로 인식, 비동기 로직 완료 후 done()이 실행하면 테스트 완료
            request(app)
                .get('/users')
                .end((err, res) => {
                    res.body.should.be.instanceOf(Array);
                    done();
                });
        });
    });
});

 

 

하면 패스된다.

 

 

그런데 테스트를 돌릴 때마다 .\node_modules\.bin\mocha .\index.spec.js 이런 명령어를 계속 사용하는 것이 번거롭다. 그래서 package.json의 스크립트에 테스트할 수 있는 속성을 추가하여 편의성을 높일 것이다.

 "scripts": {
    "test": "mocha index.spec.js"
  },

그 후 이제 테스트를 돌릴 때는 npm test 라는 명령어만 입력하면 된다!

 

 

암튼 계속 API 테스트 코드 작성 진행해보즈아아

API 테스트 코드를 할 때 성공 조건의 2번 째 요소는 limit갯수만큼의 파라미터만 받겠다는 것이었다. 이에 맞게 테스트 코드를 적으면 다음과 같다.

// index.js

describe('GET /users는 ', () => {
    describe('성공 시', () => {
        it('유저 객체를 담은 배열로 응답한다', (done) => {  
            request(app)
                .get('/users')
                .end((err, res) => {
                    res.body.should.be.instanceOf(Array);
                    done();
                });
        });
        
        // 두 번째 조건 테스트 코드 추가
        it('최대 limit 갯수만큼 응답한다', (done) => {
            request(app)
                .get('/users?limit=2')  // 쿼리스트링 형식으로 파라미터 입력. 2개까지만 받겠다
                .end((err, res) => {
                    res.body.should.have.lengthOf(2);
                    done();
                });
        });
    });
});

 

그리고 테스트를 돌리면 다음과 같은 결과가 나온다.

 

작성했던 애플리케이션 파일은 다음과 같았다.

const express = require('express');
const morgan = require('morgan');
const app = express();

const users = [
    {id: 1, name: '유재석'},
    {id: 2, name: '정준하'},
    {id: 3, name: '박명수'},
    {id: 4, name: '하하'},
];

app.use(morgan('dev'));

app.get('/users', function(req, res) {
    res.json(users);
});

app.listen(3000, function() {
    console.log('Example app listening on port 3000!');
})

module.exports = app;

 

즉 테스트코드와 맞지 않기 때문에 failing이 나온 것이고, 테스트는 정상적으로 작동됐다. 그럼 이제 원래의 index.js를 수정해야 한다.

const express = require('express');
const morgan = require('morgan');
const app = express();

const users = [
    {id: 1, name: '유재석'},
    {id: 2, name: '정준하'},
    {id: 3, name: '박명수'},
    {id: 4, name: '하하'},
];

app.use(morgan('dev'));

app.get('/users', function(req, res) {
    const limit = req.query.limit;      // 리퀘스트의 쿼리스트링에서 limit의 value 담기
    res.json(users.slice(0, limit));
});

app.listen(3000, function() {
    console.log('Example app listening on port 3000!');
})

module.exports = app;

 

테스트를 돌리면 통과!

 

 

다음은 실패 시 테스트 코드 작성해보자.

// index.spec.js


...
    describe('실패 시', () => {
        it('limit이 숫자형이 아니면 상태 코드 400 응답', (done) => {
            request(app)
                .get('/users?limit=two')
                .expect(400)
                .end(done);
        });
    });

 

애플리케이션 파일에는 req.query.limit = req.query.limit || 10; 코드를 추가한다.

// index.js


app.get('/users', function(req, res) {
    req.query.limit = req.query.limit || 10;        // limit의 값이 없다면 10
    const limit = parseInt(req.query.limit, 10);      // 리퀘스트의 쿼리스트링에서 limit의 value 담기
    if (Number.isNaN(limit)) return res.status(400).end();
    res.json(users.slice(0, limit));
});

이는 limit 파라미터가 없는 URL이 요청될 경우 10이라는 값을 넣도록 설정한 것이다. 이렇게 하면 테스트 통과.

 

실패의 또 하나 조건인 'offset이 숫자형이 아니면 400 응답' 은 DB를 붙일 때 테스트하도록 한다.

 

728x90
반응형

댓글