(24)被迫吃芒果的前端工程師 - Mocha - MongoDB 新增

前言

前面我們已經認識了基本的 Mocha 連接 MongoDB 的入門操作,那後面呢?當然就是更多的一些 Mocha 測試了。

新增資料

首先最基本的就是新增資料的部分,一樣我們要在 test 先建立一個測試的 JavaScript 檔案,叫做 create_test.js

接下來我們會使用到 Mocha 中的 describeit,所以必定要引入 Mocha

1
const { describe, it } = require("mocha");

基本上所有測試的起手式必定會是先寫 describe,因為你要先描述這個測試大區塊要做什麼,所以這邊就這樣寫

1
2
3
4
5
const { describe, it } = require("mocha");

describe('新增一筆使用者', () => {
...
})

新增完畢之後,我們要引入使用者的 Model

1
const User = require('../model/User');

引入完畢之後要做什麼呢?我們要來實例化這個資料,然後暫時儲存在變數內,請注意這邊的行為就要寫進去到 it 中,因為我們要準備做「儲存使用者」這個測試

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const { describe, it } = require("mocha");
const User = require('../model/User');

describe('新增使用者的流程測試', () => {
it('新增使用者', (done) => {
const judy = new User({
account: 'judy',
password: 'test1234',
nickname: 'judy',
age: 48,
job: '營造業',
})
})
})

it 記得參數補上 done,畢竟 MongoDB 的所有操作都會使非同步的。

前面我們已經將 judy 這個使用者給實例化了,接下來就相當簡單,只需要 save 就可以搞定,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const { describe, it } = require("mocha");
const User = require('../model/User');

describe('新增使用者的流程測試', () => {
it('新增使用者', (done) => {
const judy = new User({
account: 'judy',
password: 'test1234',
nickname: 'judy',
age: 48,
job: '營造業',
});

judy.save().then((res) => {
console.log(res);
done();
})
})
})

記得,後面要補一個 done 的 callback。

那我們現在已經完成了儲存使用者,可是這時候有一個問題來了,我們怎麼知道 judy 儲存成功了沒?其實在還沒儲存前的 judy 變數中是有一個隱藏屬性叫做 isNew 屬醒,這個屬性基本上是看不到,但是你可以用 console.dir(judy); 看到 $isNew,或者是使用 console.log(judy.isNew); 來輸出 isNew

問題來了 isNew 是什麼?這個屬性代表著這個資料是否為新的,如果還沒有儲存的話,它會是一個新屬性,因此會是 true,如果已經儲存過也就是執行過 save 的話,那就是 false

因此我們要仰賴 isNew 來幫我們斷言這個屬性是否已經成功儲存進去,所以就要引入 const assert = require('assert');,而這邊要注意 assert 如果結果是 false 是會測試失敗的,因此當我們儲存成功時 isNew 會變成 false 因此在撰寫斷言時,就要記得反轉

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const { describe, it } = require("mocha");
const User = require('../model/User');
const assert = require('assert');

describe('新增使用者的流程測試', () => {
it('新增使用者', (done) => {
const judy = new User({
account: 'judy',
password: 'test1234',
nickname: 'judy',
age: 48,
job: '營造業',
});

judy.save().then((res) => {
assert(!judy.isNew);
done();
})
})
})

接下來你就可以執行 npm run test 看結果囉

1 passing

重複新增

雖然我們前面很成功的新增了使用者資料,但是你會發現到一件事情,每一次只要你輸入一次 npm run test 之後你再去 mongoDBa 資料庫去看的話,你會發現這個奇景

重複資料

這樣子的結果其實並不是我們要的,通常來講我們會希望測試的資料可以隔絕,避免影響到其他人,每一次執行 npm run test 就新增一個使用者的話,那麼就會變成很多的 judy,所以這邊我們要來修改一下 test_helper.js 檔案。

而這邊我們將會使用到 beforeEach 這個 hook,也就是每一個測試執行之前先執行這個裡面的函式內容,而在 mongoose 中其實我們可以透過 connection.collections 撈取到當前連接的資料庫 collections,所以可以這樣子撰寫

1
2
3
beforeEach((done) => {
const { users } = mongoose.connection.collections;
})

接下來在這些 collections 中都有一個方法可以清空資料表,也就是 drop,因此寫法如下:

1
2
3
4
beforeEach((done) => {
const { users } = mongoose.connection.collections;
user.drop(() => done());
})

這樣子不管你執行幾次都不會發生重複新增的問題,因為資料都會被刪除哩。