express中间件测试mocha-chai



有没有一种方法可以在express中测试这些中间件:

module.exports = function logMatchingUrls(pattern) {
    return function (req, res, next) {
        if (pattern.test(req.url)) {
            console.log('request url', req.url);
            req.didSomething = true;
        }
        next();
    }
}

我发现的唯一中间件测试是:

module.exports = function(request, response, next) {
    /*
     * Do something to REQUEST or RESPONSE
    **/
    if (!request.didSomething) {
        console.log("dsdsd");
        request.didSomething = true;
        next();
    } else {
        // Something went wrong, throw and error
        var error = new Error();
        error.message = 'Error doing what this does'
        next(error);        
    }
};

describe('Middleware test', function(){
    context('Valid arguments are passed', function() {
        beforeEach(function(done) {
            /* 
             * before each test, reset the REQUEST and RESPONSE variables 
             * to be send into the middle ware
            **/
            requests = httpMocks.createRequest({
                method: 'GET',
                url: '/css/main.css',
                query: {
                    myid: '312'
                }
            });
            responses = httpMocks.createResponse();
            done(); // call done so that the next test can run
        });
        it('does something', function(done) {
            /*
             * Middleware expects to be passed 3 arguments: request, response, and next.
             * We are going to be manually passing REQUEST and RESPONSE into the middleware
             * and create an function callback for next in which we run our tests
            **/
            middleware(responses, responses, function next(error) {
                /*
                 * Usually, we do not pass anything into next except for errors, so because
                 * in this test we are passing valid data in REQUEST we should not get an 
                 * error to be passed in.
                **/
                if (error) { throw new Error('Expected not to receive an error'); }
                // Other Tests Against request and response
                if (!responses.didSomething) { throw new Error('Expected something to be done'); }
                done(); // call done so we can run the next test
            }); // close middleware
        }); // close it
    }); // close context
}); // close describe

这与上面提供的简单中间件(它喜欢用回调测试基本功能)配合得很好,但对于更复杂的中间件,我无法使其工作。有可能测试这种中间件吗?

这里有一个可以使用的简单设置,使用chaisinon:

var expect = require('chai').expect;
var sinon  = require('sinon');
var middleware = function logMatchingUrls(pattern) {
    return function (req, res, next) {
        if (pattern.test(req.url)) {
            console.log('request url', req.url);
            req.didSomething = true;
        }
        next();
    }
}
describe('my middleware', function() {
  describe('request handler creation', function() {
    var mw;
    beforeEach(function() {
      mw = middleware(/./);
    });
    it('should return a function()', function() {
      expect(mw).to.be.a.Function;
    });
    it('should accept three arguments', function() {
      expect(mw.length).to.equal(3);
    });
  });
  describe('request handler calling', function() {
    it('should call next() once', function() {
      var mw      = middleware(/./);
      var nextSpy = sinon.spy();
      mw({}, {}, nextSpy);
      expect(nextSpy.calledOnce).to.be.true;
    });
  });
  describe('pattern testing', function() {
    ...
  });
});

从那里,您可以为模式匹配等添加更详细的测试。由于您只使用req.url,您不必模拟整个Request对象(由Express创建),只需使用具有url属性的简单对象即可。

我使用节点模拟http来对我的中间件进行单元测试。这是我的代码:

function responseMiddleware(req, res, next) {    
    res.sendResponse = (...args) => { 
        //<==== Code removed from here
    };
    next();
}

在我的规范文件中,我是这样做的:

var expect = require('chai').expect;
var sinon  = require('sinon');    
var responseMiddleware = require('./response');
var httpMocks = require('node-mocks-http');

    describe('request handler calling', function() {
      it('should call next() once', function() {        
        var nextSpy = sinon.spy();
        responseMiddleware({}, {}, nextSpy);
        expect(nextSpy.calledOnce).to.be.true;
      });
      it('should add sendResponse key', function() {
        var nextSpy = sinon.spy();
        var req = httpMocks.createRequest();
        var res = httpMocks.createResponse();
        responseMiddleware(req, res, nextSpy);
        expect(nextSpy.calledOnce).to.be.true;
        responseMiddleware(req, res, () => {
            expect(res).to.have.property('sendResponse');        
        })        
      });
    });

如果您使用异步调用,那么您可以使用await,然后调用done()。

最新更新