【问题标题】:express middleware testing mocha chaiexpress 中间件测试 mocha chai
【发布时间】:2015-12-29 18:34:37
【问题描述】:

有没有办法在 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

这适用于上面提供的简单中间件(它就像使用回调测试基本函数),但对于更复杂的中间件,我无法让它工作。是否可以测试这种中间件?

【问题讨论】:

    标签: node.js express mocha.js


    【解决方案1】:

    这是一个您可以使用的简单设置,使用 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 属性的简单对象。

    【讨论】:

      【解决方案2】:

      我使用node-mocks-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()。

      【讨论】:

        猜你喜欢
        • 2015-11-06
        • 1970-01-01
        • 2016-09-20
        • 2016-11-15
        • 1970-01-01
        • 2020-10-11
        • 2019-02-04
        • 2017-10-21
        • 2018-02-27
        相关资源
        最近更新 更多