Node.js 使用express validator进行单元测试验证
如何对使用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
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);
}));
};