Egg.js 單元測(cè)試入門

官方推薦測(cè)試框架:MochaMocha中文網(wǎng)

官方推薦斷言庫(kù):power-assert

Egg.js 中已經(jīng)內(nèi)置 Mocha、co-mochapower-assertnyc 等模塊,只需要在 package.json 上配置好 scripts.test 即可。

{
  "scripts": {
    "test": "egg-bin test"
  }
}

運(yùn)行測(cè)試:

npm test

注意: npm test 會(huì)首先進(jìn)行 eslint 檢查,若有 error 則不會(huì)開(kāi)始測(cè)試。

指定文件路徑,可以對(duì)某一個(gè)單元測(cè)試文件進(jìn)行測(cè)試:

npm test ./path/to/user.test.js

目錄結(jié)構(gòu)

約定 test 目錄為存放所有測(cè)試腳本的目錄。

測(cè)試腳本文件統(tǒng)一按 ${filename}.test.js 命名,必須以 .test.js 作為文件后綴。

test
├── controller
│   └── home.test.js
├── hello.test.js
└── service
    └── user.test.js

Controller 測(cè)試

describeit 的第一個(gè)字段都只是描述,每一個(gè) it 是一個(gè)測(cè)試用例。

'use strict';

const { app, assert } = require('egg-mock/bootstrap');

describe('test/app/controller/home.test.js', () => {
  it('should assert', () => {
    const pkg = require('../../../package.json');
    assert(app.config.keys.startsWith(pkg.name));

    // const ctx = app.mockContext({});
    // yield ctx.service.xx();
  });

  it('should GET /', () => {
    return app.httpRequest()
      .get('/') // GET 請(qǐng)求
      .expect(200) // 期望返回的 status 200
      .expect('hi, egg'); // 期望返回的 body,支持 string/
  });
});

describe('test/app/controller/user.test.js', () => {
  it('should POST /users', () => {
    return app.httpRequest()
      .post('/users') // POST 請(qǐng)求
      .send({ username: 'Mike', password: '123456' }) // post body
      .expect(200)
      .then(response => {
        // response.text 是返回的 body 字符串,轉(zhuǎn)成 json 后再通過(guò) assert 校驗(yàn)
        const res = JSON.parse(response.text);
        assert.equal(res.code, '0000'); // 業(yè)務(wù)錯(cuò)誤碼應(yīng)該為'0000',字符串對(duì)比
        assert(res.data.userId); // userId應(yīng)該存在,注意 0、false、空字符串 都會(huì)被判定為失敗,與 assert.ok() 等效
      });
  });
});

前置和后置步驟

Mocha 使用 before/after/beforeEach/afterEach 來(lái)處理前置后置任務(wù),基本能處理所有問(wèn)題。 每個(gè)用例會(huì)按 before -> beforeEach -> it -> afterEach -> after 的順序執(zhí)行,而且可以定義多個(gè)。

describe('egg test', () => {
  // Mocha 剛開(kāi)始運(yùn)行的時(shí)候會(huì)載入所有用例,這時(shí)調(diào)用 describe 方法,執(zhí)行 before()
  before(() => console.log('order 1')); // 在當(dāng)前 describe 中的所有用例之前執(zhí)行
  before(() => console.log('order 2')); // 支持多個(gè) before 函數(shù)
  after(() => console.log('order 6')); // 在當(dāng)前 describe 中的所有用例之后執(zhí)行
  beforeEach(() => console.log('order 3')); // 在當(dāng)前 describe 中的每個(gè)用例之前執(zhí)行
  afterEach(() => console.log('order 5')); // 在當(dāng)前 describe 中的每個(gè)用例之后執(zhí)行
  it('should worker', () => console.log('order 4'));
});

Service 測(cè)試

也可以直接對(duì) Service 層進(jìn)行測(cè)試。

describe('get()', () => {
  it('should get exists user', async () => {
    // 創(chuàng)建 ctx
    const ctx = app.mockContext();
    // 通過(guò) ctx 訪問(wèn)到 service.user,直接調(diào)用 user 的方法
    const user = await ctx.service.user.get('admin');
    assert(user);
    assert(user.name === '管理員');
  });

  it('should get null when user not exists', async () => {
    const ctx = app.mockContext();
    const user = await ctx.service.user.get('admin');
    assert(!user);
  });
});
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容