Testing asynchronous function with mocha

后端 未结 3 1943
南笙
南笙 2020-12-01 10:17

I want to test a asynchronous javascript function that runs in node.js and makes a simple request to a http api:

const HOST = \'localhost\';
const PORT = 80;         


        
3条回答
  •  情歌与酒
    2020-12-01 11:04

    I've done a very similar test in my project for an http client. I paste the code here and hope is useful. Here is the client (my nodejs server use express and I use promise for error handling):

    var http = require('http');
    var querystring = require('querystring');
    
    module.exports = {
      get: function(action, params, res, callback) {
        doPromiseRequest(action, querystring.stringify(params), callback, 'GET', 'application/json')
          .then((response) => callback(response))
          .catch((error) => {
            res.status(500);
            res.render('error', {layout: false, message: error.message, code: 500});
          });
      },
    }
    
    function doPromiseRequest(action, params, callback, method, contentType) {
        var options = {
          hostname: 'localhost',
          port: 3000,
          path: '/api/v1/' + action.toString(),
          method: method,
          headers: {
            'Content-Type': contentType,
            'Content-Length': Buffer.byteLength(params)
          }
        };
    
        return new Promise( (resolve, reject) => {
    
          var req = http.request(options, 
            function(response) {
              response.setEncoding('utf8');
    
              var data = '';
              response.on('data', function(chunk) {
                data += chunk;
              });
    
              response.on('end', function() {
                var parsedResponse;
    
                try {
                  parsedResponse = JSON.parse(data);
                } catch(err) {
                  reject({message: `Invalid response from hurricane for ${action}`});
                  return;
                }
    
                if (parsedResponse.error)
                  reject(parsedResponse.error);
                else
                  resolve(parsedResponse);
              });
    
              response.on('error', function(err){
                console.log(err.message);
                reject(err);
              });
            });
    
          req.on('error', function(err) {
            console.log(err);
            reject({message: err.message});
          });
    
          req.write(params);
          req.end(); 
        });    
    }
    

    And here is the test:

    var http = require('http');
    var expect = require('chai').expect;
    var sinon = require('sinon');
    var PassThrough = require('stream').PassThrough;
    
    describe('Hurricane Client tests', function() {
      before(function() {
        this.request = sinon.stub(http, 'request');
      });
    
      after(function() {
        http.request.restore();
      });
    
      it('should convert get result to object', function(done) {
        var expected = { hello: 'world' };
        var response = new PassThrough();
        response.statusCode = 200;
        response.headers = {}
        response.write(JSON.stringify(expected));
        response.end();
    
        var request = new PassThrough();
    
        this.request.callsArgWith(1, response).returns(request);
    
        client.get('any', {}, null, function(result) {
          expect(result).to.eql(expected);
          done();
        });
      });
    });
    

提交回复
热议问题