iT邦幫忙

2023 iThome 鐵人賽

DAY 26
0

之前有幾次的面試經驗,都會提到會不會寫測試的問題,
一開始我都以為測試就只是將功能點一點看有沒有什麼問題,就可以將功能上線了,
不過規模大一點、確保程式碼品質的公司,都會強調要寫單元測試(Unit Test),/images/emoticon/emoticon13.gif
測試看看你寫的程式碼是不是會出現預期的結果。

所以今天我們就來實作單元測試看看啦~
讓我們繼續看下去。

介紹單元測試套件

來介紹這次會使用到的套件:

  • mocha
    • 下載: 在終端機下 npm install mocha 進行下載。
  • chai :
    • 下載: 在終端機下 npm install chai 進行下載。

    • 套件介紹:

      • 提供斷言庫,可以依自己使用的習慣使用 assertexpectshould 三種方式來寫斷言。
      const chai = require('chai')
      const assert = chai.assert;    // Using Assert style
      const expect = chai.expect;    // Using Expect style
      const should = chai.should()  // Using Should style
      
      • 就以 1+1 = 2 來做簡單的測試範例:

        • 使用 assert 斷言風格

          const chai = require('chai')
          const assert = chai.assert
          
          describe('Math', function() {
            it('1 + 1 should equal 2', function() {
              assert.equal(1 + 1, 2)
            })
          })
          
        • 使用 expect 斷言風格

          const chai = require('chai')
          const expect = chai.expect
          
          describe('Math', function() {
            it('1 + 1 should equal 2', function() {
              expect(1 + 1).to.equal(2)
            })
          })
          
        • 使用 should 斷言風格

          const chai = require('chai')
          chai.should()
          
          describe('Math', function() {
            it('1 + 1 should equal 2', function() {
              (1 + 1).should.equal(2)
            })
          })
          
      • 以上方式我覺得就是以你個人習慣表達方式來寫斷言,

        這次在優化專案上面我將使用 expect 的斷言風格。


實作單元測試

  1. 先建立一個 tests 的資料夾,並在底下新增一個名為 book.spec.js 的檔案。

https://ithelp.ithome.com.tw/upload/images/20230924/20162304OvnZqvEPyo.png

  1. package.json 建立執行測試腳本:

    1. scripts 的地方,新增一個名為 test 的腳本,執行命令為 NODE_ENV=local mocha tests

    2. 也就是用 mochatests 的資料夾裡面寫的測試檔案。

      https://ithelp.ithome.com.tw/upload/images/20230924/201623040eV9Jtcw40.png

  2. 開始寫單元測試: 我們使用新增書單 (POST /book) 來寫單元測試。

    1. 描述我們要做的測試,並導入我們要測試的 Controller 方法。

      const chai = require('chai')
      const BookController = require('../controllers/bookController')
      const bookController = new BookController()
      
      const expect = chai.expect
      
      describe('Book Controller', () => {
        it('should create a book successfully when validation passes', async () => {
       .... /* 測試內容 */ }
      
      	it('should handle validation errors correctly', async () => {.... /* 測試內容 */ }
      }
      
    2. 創建一個模擬的 Express request 和 response的對象。

      
      const req = {
            body: {},
            session: {
              userId: 1,
            },
          }
      const res = {
        status: function (statusCode) {
          this.statusCode = statusCode
          return this
        },
        json: function (data) {
          this.responseData = data
        },
      }
      
      
    3. 呼叫我們的方法來執行模擬的 request 。

      await bookController.createBook(req, res
      
    4. 用斷言寫出預期的結果。

      expect(res.redirectPath).to.equal('/')
      
    5. 完整程式碼

      describe('Book Controller', () => {
        it('should create a book successfully when validation passes', async () => {
          // 1. 創建一個模擬的 Express request 和 response的對象
          const req = {
            body: {
              bookName: 'Test Book',
            },
            session: {
              userId: 1,
            },
          }
          const res = {
            status: function (statusCode) {
              this.statusCode = statusCode
              return this
            },
            json: function (data) {
              this.responseData = data
            },
            redirect: function (path) {
              this.redirectPath = path
            },
          }
      
          // 2. 呼叫我們的方法來執行模擬的 request 
          await bookController.createBook(req, res)
      
          // 3. 用斷言寫出預期的結果
          expect(res.redirectPath).to.equal('/')
        })
      }
      
    6. 在終端機執行 npm run test ,看看測試有沒有過,測試通過看到療癒的綠勾勾,

      失敗的話會出現紅字顯示錯誤的原因。

      https://ithelp.ithome.com.tw/upload/images/20230924/20162304OqD63qgVIE.png


以上以第一個 should create a book successfully when validation passes 範例做講解,
第二種 should handle validation errors correctly 就留給大家式著寫寫看啦~
希望介紹完可以讓大家有對單元測試有初步的了解,
鐵人賽快結束了!!我們明天見~

參考資料:


上一篇
Day 25 - 優化專案:MVC 與 三層式架構
下一篇
Day 27 - 安全性考慮:防止常見的 Web 攻擊
系列文
30 天架設 Node.js - Express 框架:快速學習之路30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言