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) 비즈니스 로직, 테스트 로직, 서버 구동 로직이 분리되었다