2016-04-06 68 views
0

我想知道在进程中启动服务器并在相同进程中对该服务器运行测试是否存在任何缺点。在与测试相同的进程中测试node.js服务器

显然有一些性能方面的问题,但是如果我们测试的是准确性而不是性能,那么对于像下面这样的代码是否有任何主要问题?

var fs = require('fs'); 
var path = require('path'); 
var http = require('http'); 
var supertest = require('supertest'); 
var assert = require('assert'); 

describe('@Test - handleXml()*', function() { 

    var self = this; 
    var server; 
    var payload = ''; // stringified XML 
    var xmlPath = path.resolve('test', 'test_data', 'xml_payloads', 'IVR_OnDemandErrorCode.xml'); 

    before(function(done) { 
     var config = self.config = require('univ-config')(module, this.test.parent.title, 'config/test-config'); 
     server = createServer().on('listening', function() { 
      done(null); 
     }); 
    }); 

    beforeEach(function(done) { 
     fs.readFile(xmlPath, 'utf8', function(err, content) { 
      assert(err == null); 
      payload = content; 
      done(); 
     }); 
    }); 

    it('should accept request Content-type "text/xml or application/xml"', function(done) { 
     supertest(server) 
      .post('/event') 
      .set('Content-Type', 'application/xml') 
      .send(payload) 
      .expect(200, done); 
    }); 


    it('should transform XML payload into JSON object', function(done) { 
     supertest(server) 
      .post('/event') 
      .set('Content-type', 'application/xml') 
      .send(payload) 
      .expect(200) 
      .end(function(err, res) { 
       assert(err == null,'Error is not null'); 
       var jsonifiedXml = JSON.parse(res.text); 
       assert(typeof jsonifiedXml === 'object','jsonifiedXml not an object'); 
       done(); 
      }); 

    }); 

    describe('JSONified XML', function() { 

     it('should have proper key casing', function(done) { 

      supertest(server) 
       .post('/event') 
       .set('Content-type', 'application/xml') 
       .send(payload) 
       .expect(200) 
       .end(function(err, res) { 
        assert(err == null); 
        var payload = JSON.parse(res.text); 
        payload = payload.events[0].data; 
        assert(payload.hasOwnProperty('ppv'),'Bad value for ppv'); 
        assert(payload.hasOwnProperty('mac'),'Bad value for mac'); 
        assert(payload.hasOwnProperty('appName'),'Bad value for appName'); 
        assert(payload.hasOwnProperty('divisionId'),'Bad value for divisionId'); 
        assert(payload.hasOwnProperty('callTime'),'Bad value for callTime'); 
        assert(payload.hasOwnProperty('callDate'),'Bad value for callDate'); 
        assert(payload.hasOwnProperty('ivrLOB'),'Bad value for ivrLOB'); 

        done(); 
       }); 
     }); 
    }); 
}); 


function createServer(opts) { 

    //Note: this is a good pattern, definitely 

    var handleXml = require(path.resolve('lib', 'handleXml')); 

    var server = http.createServer(function(req, res) { 
     handleXml(req, res, function(err) { 
      res.statusCode = err ? (err.status || 500) : 200; 
      res.end(err ? err.message : JSON.stringify(req.body)); 
     }); 
    }); 

    server.listen(5999); //TODO: which port should this be listening on? a unused port, surely 

    return server; 
} 

回答

1

这是在节点应用程序中测试http端点的标准方式。但是你不打算在每个测试中都有一个createServer()函数。您将拥有一个通用功能,可以创建一个服务器,您可以在整个应用程序中使用这些服务器,包括启动生产服务器。

你注意到让服务器监听一个端口实际上并没有为你做任何事情。

由于这个原因,我有一种常见的做法,叫做应用程序工厂,它可以启动服务器的所有功能,但不会侦听端口。这样我就可以从测试或脚本访问服务器。生产应用程序从最小索引文件启动:

var createServer = require('./AppFactory'); 
var server = createServer(); 
server.listen(5999);