Car*_*sel 5 validation unit-testing node.js express
如何对使用express-validator完成的验证进行单元测试?
我尝试创建一个虚拟请求对象,但收到错误消息:TypeError: Object #<Object> has no method '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();
});
});
Run Code Online (Sandbox Code Playgroud)
我的理解是,checkBody当我app.use(expressValidator())在快速应用程序中使用该方法时,该方法已添加到请求对象中,但是由于我仅测试该验证在此单元测试中有效,因此我没有可用的快速应用程序实例,并且该验证我正在测试的方法无论如何都不会直接从它调用,因为它只是通过发布路由来调用,我不想调用单元测试,因为它涉及数据库操作。
这是新的 express-validator api (v4) 的解决方案:
exports.testExpressValidatorMiddleware = async (req, res, middlewares) => {
await Promise.all(middlewares.map(async (middleware) => {
await middleware(req, res, () => undefined);
}));
};
Run Code Online (Sandbox Code Playgroud)
它可以被称为像这样:
const { validationResult } = require('express-validator/check');
await testExpressValidatorMiddleware(req, res, expressValidatorMiddlewareArray);
const result = validationResult(req);
expect(result....
Run Code Online (Sandbox Code Playgroud)
这些解决方案假设您有可用的 async/await 语法。您可以使用node-mocks-http库来创建req和res对象。
express-validator 数组中的每个元素都作为中间件应用于路由。说这是你的数组:
[
check('addresses.*.street').exists(),
check('addresses.*.postalCode').isPostalCode(),
]
Run Code Online (Sandbox Code Playgroud)
每个检查都将作为中间件加载。
为了测试中间件,我们需要实现一个函数,它的作用类似于 express 实现中间件的方式。
Express 中间件总是接受三个参数,请求和响应对象,以及它应该调用的下一个函数(next按照约定)。我们为什么需要next?对于我们希望我们的中间件在处理函数之前和之后做一些事情的场景,例如
const loggerMiddleware = (req, res, next) => {
console.log('req body is ' + req.body);
next();
console.log('res status is ' + res.status);
};
Run Code Online (Sandbox Code Playgroud)
但是 express-validator 不会这样做,它只是next()在每个验证器完成后调用。出于这个原因,我们的实现并不真正需要打扰next().
相反,我们可以依次运行每个中间件并传递一个空函数next以避免出现TypeError:
middlewares.map((middleware) => {
middleware(req, res, () => undefined);
});
Run Code Online (Sandbox Code Playgroud)
但这行不通,因为 express-validator 中间件返回承诺,我们需要等待它们解决......
middlewares.map(async (middleware) => {
await middleware(req, res, () => undefined);
});
Run Code Online (Sandbox Code Playgroud)
我们不希望继续前进,直到我们迭代所有的承诺都解决了(Mozilla的文档Promise.all都在这里):
await Promise.all(middlewares.map(async (middleware) => {
await middleware(req, res, () => undefined);
}));
Run Code Online (Sandbox Code Playgroud)
我们应该将其提取为可重用的函数:
exports.testExpressValidatorMiddleware = async (req, res, middlewares) => {
await Promise.all(middlewares.map(async (middleware) => {
await middleware(req, res, () => undefined);
}));
};
Run Code Online (Sandbox Code Playgroud)
现在我们已经找到了我的解决方案。如果有人可以改进此实现,我很乐意进行编辑。
我遇到了同样的问题,我必须使用以下方法创建方法:
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;
}
Run Code Online (Sandbox Code Playgroud)
因此,在您的代码中您必须调用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();
});
});
Run Code Online (Sandbox Code Playgroud)
现在,该request对象具有bodyexpress-validator所需的属性和所有方法。
如果你想测试验证器失败的情况,你应该使用这样的东西:
function getInvalidInputRequest(request, errorParams) {
// Get de default valid request
Object.assign(request, validRequest);
// Override the validationErrors function with desired errors
request.validationErrors = function () {
var errors = [];
errorParams.forEach(function(error){
errors.push({msg: 'the parameter "'+ error +'" is mandatory'})
});
return errors;
};
return request;
}
Run Code Online (Sandbox Code Playgroud)
要更新请求,您应该执行以下操作:
request = getInvalidInputRequest(request, ['mandatory_param_1', 'mandatory_param_2']);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1961 次 |
| 最近记录: |