sitelink1 | https://tacademy.skplanet.com/live/playe...mp;seq=134 |
---|---|
sitelink2 | https://github.com/jeonghwan-kim/lecture-node-api |
sitelink3 | https://youtu.be/46VhBHkfO2o |
extra_vars4 | |
extra_vars5 | |
extra_vars6 |
1. 테스트 코드 작업 절차
1) 성공과 실패에 대한 API TEST Spec 문서 작성
> 성공::배열을 반환한다
> 성공::최대 limit 갯수만큼 응답한다
> 실패::limit이 정수가 아니면 400을 응답한다
2) 정의한 스펙에 따라 테스트 코드를 작성
const assert = require('assert')
const should = require('should')
const request = require('supertest')
const app = require('./index')
describe('GET /users', () => {
describe('성공', () => {
it('배열을 반환한다', (done) => {
...
})
it('최대 limit 갯수만큼 응답한다', (done) => {
...
})
})
describe('실패', () => {
it('limit이 정수가 아니면 400을 응답한다', (done) => {
request(app)
.get('/users?limit=two')
.expect(400)
.end(done)
})
})
})
2. GET /users
1) SUCCESS
- 유저 객체를 담은 배열로 응답한다
index.spec.js
const assert = require('assert')
const should = require('should')
const request = require('supertest')
const app = require('./index')
describe('GET /users', () => {
it('배열을 반환한다', (done) => {
request(app)
.get('/users')
.end((err, res) => {
res.body.should.be.instanceof(Array)
res.body.forEach(user => {
user.should.have.property('name')
})
done()
})
})
})
index.js
const express = require('express')
const logger = require('morgan')
const app = express()
const users = [
{id:1, name:'Alice'},
{id:2, name:'Bek'},
{id:3, name:'Chris'}
]
app.get('/', (req, res) => res.send('Hello World!!'))
app.get('/users', (req, res) => res.json(users))
module.exports = app
- 최대 limit 갯수만큼 응답한다
index.spec.js
const assert = require('assert')
const should = require('should')
const request = require('supertest')
const app = require('./index')
describe('GET /users', () => {
it('배열을 반환한다', (done) => {
request(app)
.get('/users')
.end((err, res) => {
res.body.should.be.instanceof(Array)
res.body.forEach(user => {
user.should.have.property('name')
})
done()
})
})
it('최대 limit 갯수만큼 응답한다', (done) => {
request(app)
.get('/users?limit=2')
.end((err, res) => {
res.body.should.have.length(2)
done()
})
})
})
index.js
const express = require('express')
const logger = require('morgan')
const app = express()
const users = [
{id:1, name:'Alice'},
{id:2, name:'Bek'},
{id:3, name:'Chris'}
]
app.get('/', (req, res) => res.send('Hello World!!'))
app.get('/users', (req, res) => {
req.query.limit = req.query.limit || 10 // 디폴트는 10
const limit = parseInt(req.query.limit, 10)
res.json(users.slice(0, limit))
})
module.exports = app
2) ERROR
- limit이 숫자형이 아니면 400을 응답한다
index.spec.js
const assert = require('assert')
const should = require('should')
const request = require('supertest')
const app = require('./index')
describe('GET /users', () => {
describe('성공', () => {
it('배열을 반환한다', (done) => {
})
it('최대 limit 갯수만큼 응답한다', (done) => {
})
})
describe('실패', () => {
it('limit이 정수가 아니면 400을 응답한다', (done) => {
request(app)
.get('/users?limit=two')
.expect(400)
.end(done)
})
})
})
index.js
const express = require('express')
const logger = require('morgan')
const app = express()
const users = [
{id:1, name:'Alice'},
{id:2, name:'Bek'},
{id:3, name:'Chris'}
]
app.get('/', (req, res) => res.send('Hello World!!'))
app.get('/users', (req, res) => {
req.query.limit = req.query.limit || 10 // 디폴트는 10
const limit = parseInt(req.query.limit, 10)
if (limit === NaN) {
res.status(400).end()
} else {
res.json(users.slice(0, limit))
}
})
module.exports = app
- offset이 숫자형이 아니면 400을 응답한다
index.spec.js
index.js
3. 서버 프로그램을 테스트 하는 팁 (npm start시 'www.js'로 구동)
index.js 에는 서버 운영상의 모든 비즈니스 로직이 정의되어 있는데
서버 구동 코드인 app.listen(3000, () => console.log('running')) 도 혼재되어 있기 때문에
index.js 의 비즈니스 코드를 테스트해야 하는 index.spec.js 에서 index를 require하고 테스트 실행시엔 index.js의 서버 구동 코드를 주석해줘야 했다
이러한 불편함을 해결하기 위해 서버 구동코드를 www.js로 별도로 분리하여 서버 구동시 www.js를 지정할 수 있도록 한다
1) index.js 에서 express의 구현체인 app 객체를 export한다
> module.exports = app
2) 웹서버를 구동하는 모듈을 정의하는 bin/www.js 파일을 생성
> const app = require('../index') 로 index.js 를 import (js확장자는 생략가능)
3) 생성한 bin/www.js 파일에 app 객체를 구동하는 코드를 정의한다
> app.listen(3000, () => console.log('running'))
4) package.json 에 start 선언부를 www.js 로 바꾼다
> "start" : "node ./bin/www" (js확장자는 생략가능)
5) 비즈니스 로직, 테스트 로직, 서버 구동 로직이 분리되었다
댓글 0
번호 | 제목 | 글쓴이 | 날짜 | 조회 수 |
---|---|---|---|---|
5 | [TDD/REST-7강] 코드 리팩토링 (express.Router, control) | 황제낙엽 | 2020.12.04 | 87 |
4 | [TDD/REST-6강] 사용자 API 개발 | 황제낙엽 | 2020.12.03 | 81 |
3 |
[TDD/REST-목차][T아카데미] Node.js 기반의 REST API 서버 개발
![]() | 황제낙엽 | 2020.12.03 | 77 |
» | [TDD/REST-5강] TDD로 API 서버 개발 (작업절차, get users 테스트) | 황제낙엽 | 2020.12.01 | 82 |
1 | [TDD/REST-4강] TDD 이해 및 환경 구축 (Rest API, TDD, mocha, Should, SuperTest) | 황제낙엽 | 2020.12.01 | 83 |