Skip to content

Instantly share code, notes, and snippets.

@idhowardgj94
Forked from mrister/runt_test.sh
Last active November 5, 2018 07:53
Show Gist options
  • Save idhowardgj94/7b11fbd668366cf6d03585799537e84e to your computer and use it in GitHub Desktop.
Save idhowardgj94/7b11fbd668366cf6d03585799537e84e to your computer and use it in GitHub Desktop.
Mocha and chai example

使用mocha測試純前端的javascrit

網路上搜尋到的範例中,通常都是mocha搭配chai,測試nodejs伺服器端的程式。 要如何測試純前端讀取的javascript file呢?

nodejs的javascript,透過模組化的概念,每寫完一個function 後,必須把function export成一個模組, 在測試檔案中使用require(filepath/file)引入後,才可以對其作測試。

然而目前的網頁瀏覽器都還不認識ES6 的 export 寫法。 如果要使用這架構開發測試,最後還要經過webpack之類的程序,將ES6的 js code 編譯成目前瀏覽器看得懂的js版本。 其實是一個不小的負擔。

其實也可以直接測試瀏覽器看得懂的前端js檔案。但是必須是支援模組概念的js code才行。

再純js中,沒有所謂的class,所有的組成都是objectfunction。在 javascript中,global環境即是一個object。任何新產生的 function,都是一個都會掛在global物件之下。然而,nodejs中,為了要實現模塊化,因此檔案跟檔案之間的global物件是不共享的。 這跟傳統瀏覽器編譯的js行為不一樣。傳統的瀏覽器編譯js,會將所有宣告的function掛在共同的global下,也就是window(大概吧,沒求証過)

因此,要透過mocha測試前端code,就是要想辦法讓程式碼產生 export 的效果。

下面為其中一種方式(沒有在瀏覽器端測試過,不失用起來會不會不一樣):

// first.js
(function(exports) {
  "use strict";
  function firstFun() {
    return "hello, howard";
  }
  exports.first = firstFun;
})(this);


//first.test.js
var chai = require('chai');
var assert = chai.assert;
var first = require('./first');

describe('FirstTestFromOtherFile', function () {
  var ans = 'hello, howard';
  it('should be equal', function() {
    assert(ans === first.first(), 'return value is not equal');
  });
});

this 以及 window(global)

引用:https://wcc723.github.io/javascript/2017/12/15/javascript-use-strict/

"use strict"模式下,function 內的 this不再是window物件。 除非有使用bindthiswindow bind 起來。 如此可以區隔開不同的function的global scope,在實作模組化的時候比較不會發生問題。

#!/usr/bin/env bash
# make soure you have mocha installed
npm i mocha -g
# run tests with mocha
mocha --reporter=spec test.spec.js
var chai = require('chai');
var expect = chai.expect;
var assert = chai.assert;
var testObj = {
name: "test",
sub: {
name: 'test sub'
},
numbers: [1, 2, 3, 4],
hasNumbers : true
};
describe ('Test Suite', function () {
describe('expect tests', function () {
it ('should be a valid testObject', function () {
expect(testObj).to.be.an('object').and.is.ok;
expect(testObj).to.have.property('sub').that.is.an('object').and.is.ok;
expect(testObj.sub).to.have.property('name').that.is.a('string').and.to.equal('test sub');
expect(testObj).to.have.property('numbers').that.deep.equals([1, 2, 3, 4]);
expect(testObj).to.have.property('hasNumbers', true);
});
});
describe('assert tests', function () {
it ('should be a valid testObject', function () {
assert.isOk(testObj);
assert.isObject(testObj);
assert.propertyVal(testObj, 'name', 'test');
assert.property(testObj, 'sub');
assert.propertyVal(testObj.sub, 'name', 'test sub');
assert.property(testObj, 'sub');
assert.deepEqual(testObj.numbers, [1, 2, 3, 4]);
assert.typeOf(testObj.hasNumbers, 'boolean');
assert.isTrue(testObj.hasNumbers);
});
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment