Node.js 使用express validator进行单元测试验证

Node.js 使用express validator进行单元测试验证,node.js,validation,unit-testing,express,Node.js,Validation,Unit Testing,Express,如何对使用express validator完成的验证进行单元测试 我尝试创建一个虚拟请求对象,但我得到了错误:TypeError:object\35;没有方法“checkBody”。我能够手动测试验证在应用程序中是否有效 以下是我尝试过的: describe('couponModel', function () { it('returns errors when necessary fields are empty', function(done){ var testB

如何对使用express validator完成的验证进行单元测试

我尝试创建一个虚拟请求对象,但我得到了错误:
TypeError:object\35;没有方法“checkBody”
。我能够手动测试验证在应用程序中是否有效

以下是我尝试过的:

describe('couponModel', function () {
    it('returns errors when necessary fields are empty', function(done){
        var testBody = {
            merchant : '',
            startDate : '',
            endDate : ''
        };
        var request = {
            body : testBody
        };
        var errors = Model.validateCouponForm(request);
        errors.should.not.be.empty;
        done();
    });
});

我的理解是,当我在express应用程序中使用(expressValidator())app.use时,
checkBody
方法会添加到请求对象中,但由于我只是在测试验证是否在此单元测试中起作用,因此我没有express应用程序的实例可用,我正在测试的验证方法并不是直接从它调用的,因为它只是通过post路由调用的,我不想为单元测试调用post路由,因为它涉及数据库操作。

我面临同样的问题,我必须使用以下方法创建方法:

var validRequest = {
  // Default validations used
  checkBody: function () { return this; },
  checkQuery: function () { return this; },
  notEmpty: function () { return this; },

  // Custom validations used
  isArray: function () { return this; },
  gte: function () { return this; },

  // Validation errors
  validationErrors: function () { return false; }
};

function getValidInputRequest(request) {
    Object.assign(request, validRequest);
    return request;
}
因此,在代码中,您必须调用
getValidInputRequest
帮助程序:

describe('couponModel', function () {
  it('returns errors when necessary fields are empty', function(done){
      var testBody = {
          merchant : '',
          startDate : '',
          endDate : ''
      };
      var request = {
          body : testBody
      };

      request = getValidInputRequest(request); // <-- Update the request

      var errors = Model.validateCouponForm(request);
      errors.should.not.be.empty;
      done();
  });
});
要更新请求,您应执行以下操作:

request = getInvalidInputRequest(request, ['mandatory_param_1', 'mandatory_param_2']);

下面是新的express validator api(v4)的解决方案:

tl;dr:您可以使用此功能: 可以这样称呼:

const { validationResult } = require('express-validator/check');

await testExpressValidatorMiddleware(req, res, expressValidatorMiddlewareArray);
const result = validationResult(req);
expect(result....
这些解决方案假定您具有异步/等待语法。您可以使用该库创建
req
res
对象

说明:
express验证器数组中的每个元素都作为中间件应用于路由。假设这是您的阵列:

[
  check('addresses.*.street').exists(),
  check('addresses.*.postalCode').isPostalCode(),
]
每个检查都将作为中间件加载

为了测试中间件,我们需要实现一个功能,其作用类似于express实现中间件的方式

Express中间件始终接受三个参数,即请求和响应对象,以及它应该调用的下一个函数(
next
)。为什么我们需要
下一步
?对于希望中间件在继续功能之前和之后执行某些操作的场景,例如

const loggerMiddleware = (req, res, next) => {
  console.log('req body is ' + req.body);
  next();
  console.log('res status is ' + res.status);
};
但是express validator不这样做,它只在每个验证器完成后调用
next()
。因此,我们的实现实际上不需要为
next()
操心

相反,我们可以依次运行每个中间件,并将空函数传递为
next
,以避免出现
TypeError

middlewares.map((middleware) => {
  middleware(req, res, () => undefined);
});
但这不会起作用,因为ExpressValidator中间件会返回承诺,我们需要等待它们得到解决

middlewares.map(async (middleware) => {
  await middleware(req, res, () => undefined);
});
在迭代中的所有承诺都得到解决之前,我们不想继续前进(Mozilla文档位于
Promise.all
上):

我们应该将其提取为可重用函数:

exports.testExpressValidatorMiddleware = async (req, res, middlewares) => {
  await Promise.all(middlewares.map(async (middleware) => {
    await middleware(req, res, () => undefined);
  }));
};
现在我们已经找到了我的解决方案。如果有人能改进这个实现,我很乐意进行编辑

middlewares.map(async (middleware) => {
  await middleware(req, res, () => undefined);
});
await Promise.all(middlewares.map(async (middleware) => {
  await middleware(req, res, () => undefined);
}));
exports.testExpressValidatorMiddleware = async (req, res, middlewares) => {
  await Promise.all(middlewares.map(async (middleware) => {
    await middleware(req, res, () => undefined);
  }));
};