使用 Jasmine 測試 Node 項目


在上一篇文章( Jasmine Introdunction)中,我們已經介紹了如何在瀏覽器中運行 Jasmine 測試框架。對於瀏覽器端的 JS 代碼來說,這無疑是很方便的。那么 Jasmine 能否用來對服務端的代碼進行測試呢?答案當然是可以。本文中,我們就將介紹如何在基於 Node 的項目中,方便快捷地運行 Jasmine 測試。
 
同上篇文章一樣,我們依舊新建一個待測試的 JS 文件 js/Hello.js
function Hello() {};

Hello.prototype.foo = "foo";
Hello.prototype.bar = null    ;

Hello.prototype.helloWorld = function() {
    return "Hello World!";
}

Hello.prototype.helloSomeone = function(toGreet) {
    return this.sayHello() + " " + toGreet;
}

Hello.prototype.sayHello = function() {
    return "Hello";
}

module.exports = Hello;
View Code

 

 
安裝 Jasmine Module
首先,使用 npm 全局安裝 jasmine 模塊:
npm install -g jasmine
 
進行全局安裝后,我們就可以直接在終端執行 jasmine 命令了。執行:
jasmine -v
就可以看到當前安裝的 jasmine 版本。這里我安裝的版本為 jasmine v2.4.1。
 
初始化
接下來,我們就需要對測試項目進行初始化了。我們可以手動進行初始化,但更簡單的方式是直接在項目目錄下運行命令:
jasmine init
  
jasmine 會在當前目錄下生成一個配置文件 spec/support/jasmine.json
{
  "spec_dir": "spec",
  "spec_files": [
    "**/*[sS]pec.js"
  ],
  "helpers": [
    "helpers/**/*.js"
  ],
  "stopSpecOnExpectationFailure": false,
  "random": false
}
其中    spec_dir: 指定掃描測試文件的根目錄
          spec_files: 匹配測試文件的表達式
          helpers: Helper 文件會在所有的 spec 之前預先執行
          stopSpecOnExpectationFailure: 當有錯誤出現時是否終止所有測試
          random: 是否打亂測試順序
 
 
添加測試代碼
接下來,就該添加我們的測試代碼了。分別添加 spec/Hello.spec.js
describe("Hello", function () {
    var Hello = require("../js/Hello");
    var hello;

    beforeEach(function () {
        hello = new Hello();
    });

    it("a newly created Hello instance should not be the same instance with the origin one", function () {
        expect(hello).not.toBe(new Hello());
        expect(hello).toEqual(new Hello());
    });

    describe("helloWorld function", function () {
        it("should return hello statement", function () {
            expect(hello.helloWorld()).toBe("Hello World!");
        });

        it("should contain word 'World'", function () {
            expect(hello.helloWorld()).toContainWord("World!");
        });

        it("an undefined variable should pass 'toBeUndefined' matcher", function () {
            expect(hello.a).toBeUndefined();
        });

        it("a null variable should pass 'toBeNull' matcher", function () {
            expect(hello.bar).toBeNull();
        });

        it("variable after boolean casting should pass 'toBeTruthy' 'toBeFalsy' matcher", function () {
            expect(hello.foo).toBeTruthy();
            expect(hello.bar).toBeFalsy();
        });
        it("should pass the 'toMatch' matcher for regular expressions", function (){
            expect(hello.helloWorld()).toMatch(/^\w*\s\w*!$/);
        });
    });

    describe("helloSomeone function", function () {
        it("should calls the sayHello() function", function () {
            spyOn(hello, "sayHello");
            hello.helloSomeone("Chou");
            expect(hello.sayHello).toHaveBeenCalled();
            expect(hello.sayHello).toHaveBeenCalledTimes(1);
        });
        it("should greet the 'World'", function () {
            spyOn(hello, "helloSomeone");
            hello.helloSomeone("World");
            expect(hello.helloSomeone).toHaveBeenCalledWith("World");
            expect(hello.helloSomeone).not.toHaveBeenCalledWith("world");
        });
        it("should calls the fake sayHello()", function () {
            hello.sayHello = jasmine.createSpy("'sayHello' spy");
            hello.helloSomeone("world");
            expect(hello.sayHello).toHaveBeenCalled();
        });
    });
});
View Code
spec/helpers/SpecHelper.js
beforeEach(function () {
    jasmine.addMatchers({
        toContainWord: function () {
            return {
                compare: function (actual, expected) {
                    var result = {};
                    result.pass = (actual.indexOf(expected) !== -1);
                    if( result.pass ) {
                        result.message = "Expected " + actual + " to contain " + expected + ".";
                    } else {
                        result.message = "Expected " + actual + " to contain " + expected + ", but it does not.";
                    }
                    return result;
                }
            }
        }
    });
});
View Code
(若對測試代碼有疑問,請移步 Jasmine Introdunction)
 
 
運行測試
當我們添加了測試代碼,並且配置好了配置文件 jasmine.json ,就可以回到根目錄下,直接執行命令:
jasmine
 
就可以看到我們的 10 個測試用例全部順利通過了。不過每個通過的測試,只是由一個綠色的點表示。很多時候,我們都希望能夠看到全部的測試用例,以及不同測試用例之間的層級關系,僅是一個綠色的小點並不利於我們進行調試。這里我們再介紹一個模塊: jasmine-spec-reporter 能夠很好地解決這個問題。
 
首先,執行如下命令在本地安裝 jasmine 和 jasmine-spec-reporter
npm install jasmine --save-dev
npm install jasmine-spec-reporter --save-dev
 
然后在項目根目錄,添加 jasmine-runner.js
var Jasmine = require('jasmine');
var SpecReporter = require('jasmine-spec-reporter');
var noop = function() {};

var jrunner = new Jasmine();
jrunner.configureDefaultReporter({print: noop});    // remove default reporter logs
jasmine.getEnv().addReporter(new SpecReporter());   // add jasmine-spec-reporter
jrunner.loadConfigFile();                           // load jasmine.json configuration
jrunner.execute();
View Code
這段代碼展示了在沒有全局安裝 jasmine 時,如何通過調用 library 來使用 jasmine 測試框架測試我們的代碼。
運行命令:
node jasmine-runner.js
  
現在的輸出是否更清晰明了了呢~
 
到目前為止,我們已經介紹了如何使用 Jasmine 測試框架來對 Node 項目進行測試。希望本文能對你有所幫助。如果你覺得本文有任何問題,還望不吝賜教。
 
 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM