7_ TDD로 하는 API 서버 개발

YoonJu Lee·2021년 7월 25일
0

사용자 목룍 조회 API 테스트 코드 만들기 1

  • 요구사항
    성공
    1) 유저 객체를 담은 배열로 응답한다
    2) 최대 limit 갯수만큼 응답한다
    • 실패
    3) limit이 숫자형이 아니면 400을 응답한다
    4) offset이 숫자형이 아니면 400을 응답한다
    ( 데이터가 많을 경우, 잘라서 받는데 앞의 데이터를 몇 개 skip 하고 달라고 하는 경우가 있다. 이 때 skip한 갯수가 offset 변수에 들어간다.

요구사항 따라 작성학.

1_ Spec_01. 유저 객체를 담은 배열로 응답한다

1) 코드

< index.spec.js >

const request = require('supertest') // supertest 모듈 가져옴
const should = require('should')
const app = require('./index') // 테스트 하는 파일

// test 코드 작성
// test suit : describe
describe('GET /users는', () => {
  describe('성공시', () => {
    it('user 객체를 담은 배열로 응답한다.', (done) => {
      request(app)
        .get('/users')
        .end((err, res) => {
          // 배열이라는 것 검증 - should
          res.body.should.be.instanceOf(Array)
          done()
        })
    })
  })

})

2) 결과 화면

* NPM 테스트 스크립트

: package.json 파일에서 script 값에 'test'를 변경하여, 긴 명령어를 치지 않아도 index.spec.js 파일이 실행되도록 script를 변경한다.

실행 명령어 & 실행 화면

3. Spec_02.최대 limit 갯수만큼 응답한다.

1) test case 추가.

< 추가 >

it('최대 limit 갯수만큼 응답한다.', (done) => {
      request(app)
        .get('/users?limit=2') // user리스트를 2개만 받겠다! 라는 의미
        .end((err, res) => {

          res.body.should.have.lengthOf(2)
          done()
        })
    })
  })

< index.spec.js > 전체 코드

const request = require('supertest') // supertest 모듈 가져옴
const should = require('should')
const app = require('./index') // 테스트 하는 파일

// test 코드 작성
// test suit : describe
describe('GET /users는', () => {
  describe('성공시', () => {
    it('user 객체를 담은 배열로 응답한다.', (done) => {
      request(app)
        .get('/users')
        .end((err, res) => {
          // 배열이라는 것 검증 - should
          res.body.should.be.instanceOf(Array)
          done()
        })
    })

    it('최대 limit 갯수만큼 응답한다.', (done) => {
      request(app)
        .get('/users?limit=2') // user리스트를 2개만 받겠다! 라는 의미
        .end((err, res) => {

          res.body.should.have.lengthOf(2)
          done()
        })
    })
  })

})

2) 결과 화면._ Fail


: exprectedArray 의 length는 3인데, 기대를 2를 해서 실패했따.

3) 성공하도록, 실제 application 코드를 변경


const express = require('express')
const app = express()
const morgan = require('morgan')
const port = 3000
const users = [
  { id: 1, name: 'bek' },
  { id: 2, name: 'alice' },
  { id: 3, name: 'chris' },
]
// DB가 없으므로, 일단 배열을 넣어봄. 

app.use(morgan('dev'))

app.get('/users', (req, res) => {
   const limit = req.query.limit; // "2"로 문자열임. 따라서, 정수형으로 바꿔주야한다. 
  res.json(users.slice(0, limit))
})

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`)
})

// 지금까지는 객체를 할당하였으나, 변수를 할당하여도 괜찮음!
module.exports = app;

4) 성공 test 결과 화면

4_Spec_03. 실패) limit이 숫자형이 아니면 400을 응답한다

  • index.spec.js 파일에 실패시의 suitcase 만듬

1) 코드

< index.spec.js >코드 추가

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

2) 실행 화면

:Fail 이 뜰 것이다. 왜냐하면 application코드를 수정하지 않았으므로.

3) 코드

<index.js>

app.get('/users', (req, res) => {
  // const limit = req.query.limit; // "2"로 문자열임. 따라서, 정수형으로 바꿔주야한다. 
  const limit = parseInt(req.query.limit, 10) // (수로 바꿀 문자열, 10진법)
  if (Number.isNaN(limit)) {
    // limit이 NaN이면 정수가 아니라는 뜻!
    return res.status(400).end()
    // 지금까지는 status(200)을 쓰지 않았는데,이유는 기본이 200으로 되어있어서.
    // 마지막에 end 함수 : 돌려준다!
  }
  res.json(users.slice(0, limit))
})

4) 결과 화면


: 빈 객체가 돌아왔다고 fail이 뜸!

5) Fail 이 된이유!

spec_01에서..


는 limit 변수가 없다.

그런데, application의 코드에서는 limit변수가 있다!!

해석 )

첫번쨰 testcase에서는 limit변수가 없으므로,
applicaion에서 limit 값이 undefind로 들어온다.
따라서, limit이 NaN이 들어오므로 상태코드가 400을 내뱉는다.

6) 해결!

applicaion의 코드안에 코드추가

  req.query.limit = req.query.limit || 10;
  //  req.query.limit || 10   --- 의미
  // : req.query.limit 의 숫자가 있으면 그대로 쓰꼬,
  // 없으면, 10을 기본값으로 준다. 

index.js 전체 코드.


const express = require('express')
const app = express()
const morgan = require('morgan')
const port = 3000
const users = [
  { id: 1, name: 'bek' },
  { id: 2, name: 'alice' },
  { id: 3, name: 'chris' },
]
// DB가 없으므로, 일단 배열을 넣어봄. 

app.use(morgan('dev'))

app.get('/users', (req, res) => {
  // const limit = req.query.limit; // "2"로 문자열임. 따라서, 정수형으로 바꿔주야한다. 
  req.query.limit = req.query.limit || 10;
  //  req.query.limit || 10   --- 의미
  // : req.query.limit 의 숫자가 있으면 그대로 쓰꼬,
  // 없으면, 10을 기본값으로 준다. 
  const limit = parseInt(req.query.limit, 10) // (수로 바꿀 문자열, 10진법)
  if (Number.isNaN(limit)) {
    // limit이 NaN이면 정수가 아니라는 뜻!
    return res.status(400).end()
    // 지금까지는 status(200)을 쓰지 않았는데,이유는 기본이 200으로 되어있어서.
    // 마지막에 end 함수 : 돌려준다!
  }
  res.json(users.slice(0, limit))
})

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`)
})

// 지금까지는 객체를 할당하였으나, 변수를 할당하여도 괜찮음!
module.exports = app;


7) 전체 실행 화면

profile
Coder가 아닌 Engineer를 향해서.

0개의 댓글