※ 인프런 - 테스트주도개발(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를 붙일 때 테스트하도록 한다.
'개발자 도전기 > [STUDY] TEST CODE' 카테고리의 다른 글
Node.js | TEST | 통합 테스트 시 사용하는 라이브러리 분석, 비교 해보기: [axios, supertest, chai-http, axiosist 등등등] (0) | 2022.09.21 |
---|---|
TDD | node.js | 사용자 조회, 삭제, 추가, 수정 API 테스트 (0) | 2022.05.24 |
TDD | 테스트 주도 개발? (0) | 2022.05.09 |
댓글