iT邦幫忙

DAY 16
5

node.js伺服器實戰系列 第 16

node.js伺服器實戰(16) - 可測試性

  • 分享至 

  • xImage
  •  

單元測試並不是直接就可以做的,還必須讓程式「可測試」。
問題點

要開始做單元測試時,會發現一件事情

  1. 位於主程式內的函數,無法進行單元測試
  2. 所以需要把這些東西拿出來,作成模組

之前的evolve.js主程式長這樣:

https://github.com/fillano/evolve/blob/8e7269d5bfccd9e616af00f87d9f2d9db80f1dd1/lib/evolve.js(太長了,請到github看XD

現在把tools拆出來成為tools.js:

https://github.com/fillano/evolve/blob/13cbf9ec2629bd02e15c350564c1537cc9ba292a/lib/tools.js(還是太長)

這樣evolve.js主程式就只剩下:

 var http = require('http'),
     tools = require('./tools');
 
 var count = 0;
 
 var evolve = function(conf) {
     var server = http.createServer(function(request, response) {
         console.log(process.pid + '::' + ++count + ': ' + process.memoryUsage().heapUsed);
         tools.dispatch(conf, request, response, function(err, realpath, data) {
             if(err) {
                 console.log(process.pid + '::' + realpath + ' not exists.');
                 response.writeHead(404, {"Content-Type":"text/html"});
                 response.end('<h1>404: Request resource not found.</h1>');
             } else {
                console.log(process.pid + '::' + realpath + ' exists.');
                response.writeHead(200, {
                    "Content-Type": data.type,
                    "Content-Length": data.data.length
                });
                response.end(data.data);
             }
         });
     });
     this.listen = function(port, addr) {
         server.listen(port, addr);
         return this;
     };
     this.host = tools.hostHandler;
 };
 module.exports = evolve;

一方面變得更精簡,另一方面要開始調整伺服器的細部結構時,這樣應該會更容易。

針對模組做單元測試

先對cache做簡單的測試(testCache.js):

 var testCase = require('nodeunit').testCase;
 
 module.exports = testCase({
     setUp: function(cb) {
         this.cache = require('../lib/cache');
         this.target = {type: 'foo', value: 'bar'};
         cb();
     },
     tearDown: function(cb) {
         this.cache = null;
         delete this.cache;
         this.target = null;
         delete this.target;
         cb();
     },
     "test cache.regist": function(test) {
         test.expect(2);
         this.cache.put('foo', 'bar', this.target);
         test.equal(typeof this.cache.get('foo', 'bar'), 'undefined', 'cache.get to unregisted cache type will got undefined.');
         this.cache.regist('foo');
         this.cache.put('foo', 'bar', this.target);
         test.deepEqual(this.cache.get('foo', 'bar'), this.target, 'cache.put an object and then cache.get the object.');
         test.done();
     },
     "test cache.del": function(test) {
         test.expect(2);
         this.cache.regist('none');
         this.cache.put('none', 'foo', this.target);
         test.deepEqual(this.cache.get('none', 'foo'), this.target, 'confirm object get from cache is matched.');
         this.cache.del('none', 'foo');
         test.equal(typeof this.cache.get('none', 'foo'), 'undefined', 'delete from cache and test the deleted will become undefined.');
         test.done();
     },
     "test cache.query": function(test) {
         test.expect(2);
         this.cache.regist('fs');
         test.equal(this.cache.query('fs', 'foo'), false, 'cache.query with non existed item will return false.');
         this.cache.put('fs', 'foo', this.target);
         test.equal(this.cache.query('fs', 'foo'), true, 'cache.query with existed item will return true.');
         test.done();
     }
 });

接下來對tools.getRes做簡單的測試(testGetRes.js):

 var testCase = require('nodeunit').testCase;
 var path = require('path');
 
 module.exports = testCase({
     setUp: function(cb) {
         this.getRes = require('../lib/tools').getRes;
         cb();
     },
     tearDown: function(cb) {
         this.getRes = null;
         delete this.getRes;
         cb();
     },
     "test tools.getRes": function(test) {
         test.expect(4);
         this.getRes(path.join(__dirname, '../www'), ['index.html', 'index.htm', 'default.htm'], function(err, respath, data) {
             test.equal(err, false);
             test.equal(data.type, 'text/html');
             test.equal(Buffer.isBuffer(data.data), true);
             test.ok(data.data.toString().indexOf('index')>-1);
             test.done();
         });
     }
 });

改過build.xml之後跑測試:

D:\fillano\Dropbox\Shared\evolve>ant unittest
Buildfile: D:\fillano\Dropbox\Shared\evolve\build.xml

unittest:
     [exec]
     [exec] testRouter.js
     [exec] ok: testAddHost
     [exec]
     [exec] testGetRes.js
     [exec] ok: test tools.getRes
     [exec]
     [exec] testCache.js
     [exec] ok: test cache.regist
     [exec] ok: test cache.del
     [exec] ok: t
     [exec] est cache.query
     [exec]
     [exec] OK: 11 assertions (23ms)

BUILD SUCCESSFUL
Total time: 0 seconds

雖然結果有奇怪的折行,不過看起來還是通過測試了。(用nodeunit跑其實不會有這個問題)

即使是單元測試,也只保證所測試的「單元」沒有問題,但是怎麼知道所有東西兜起來也沒問題呢?這就要靠整合測試了。明天再來弄吧。

相關文章


上一篇
node.js伺服器實戰(15) - 單元測試
下一篇
node.js伺服器實戰(17) - 整合測試
系列文
node.js伺服器實戰33
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言