node.js - 使用自定义错误处理程序时,是否可以使用 Mocha 测试 ExpressJS 中的错误处理?

标签 node.js express testing mocha.js integration-testing

测试

    it('should fail trying to GET bookmarks with false user id',async () => {
      try {
        const response = await request(app)
          .get(baseApiUrlUnderTest + 'false_user_id/bookmarks')
          .set('Authorization', bearerToken);
      } catch (e) {
        console.log(e); //it doesn't reach this point
        expect(e.httpStatus).to.equal(HttpStatus.UNAUTHORIZED);
      }
    });

被测方法的相关部分:

/* GET bookmark of user */
personalBookmarksRouter.get('/', keycloak.protect(), wrapAsync(async (request, response) => {

  userIdTokenValidator.validateUserIdInToken(request);
 ...
}));

其中 wrapAsync 确保将错误传递给自定义错误处理程序:

let wrapAsync = function (fn) {
  return function(req, res, next) {
    // Make sure to `.catch()` any errors and pass them along to the `next()`
    // middleware in the chain, in this case the error handler.
    fn(req, res, next).catch(next);
  };
}

导致被测方法抛出异常的validateUserIdInToken方法:

const AppError = require('../models/error');
const HttpStatus = require('http-status-codes');

let validateUserIdInToken = function (request) {
  const userId = request.kauth.grant.access_token.content.sub;
  if ( userId !== request.params.userId ) {
    throw new AppError(HttpStatus.UNAUTHORIZED, 'Unauthorized', ['the userId does not match the subject in the access token']);
  }
}

module.exports.validateUserIdInToken = validateUserIdInToken;

以及根中间件中的自定义错误处理程序:

app.use(function(err, req, res, next) {
  if (res.headersSent) {
    return next(err)
  }
  if(err instanceof AppError) { //execution lands here as expected and the test stops...
    res.status(err.httpStatus);
    return res.send(err);
  } else {
    res.status(err.status || HttpStatus.INTERNAL_SERVER_ERROR);
    res.send({
      message: err.message,
      error: {}
    });
  }

});

最佳答案

我认为您可能没有正确处理这个问题。无效的身份验证不应在应用程序中引发错误 - 这实际上不是错误,而是验证问题。

如果身份验证失败,只需将相关的 http 错误代码 - 401 发送回客户端即可。

res.send(HttpStatus.UNAUTHORIZED, 'a message if you want'); // 401

在您的路由处理程序中:

personalBookmarksRouter.get('/', keycloak.protect(), wrapAsync(async (request, response) => {
  const userId = request.kauth.grant.access_token.content.sub;
  if ( userId !== request.params.userId ) {
     return response.send(HttpStatus.UNAUTHORIZED);
  }

 ...
}));

在您的测试中,检查状态 401:

chai.request(server)
    .get('/false_user_id/bookmarks')
    .end((err, result) => {
        if (err) {
            return callback(err);
        }

        result.should.have.status(401);
    });

关于node.js - 使用自定义错误处理程序时,是否可以使用 Mocha 测试 ExpressJS 中的错误处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58933323/

相关文章:

node.js - NodeJS/Express 自动检测 SSL over HTTP (HTTPS) 解释?

node.js - 使用node.js(带有express)作为静态网络服务器

node.js - Node 。绕过登录屏幕上图像的身份验证

node.js - Express 无需 app.listen 或服务器即可工作

node.js - 我们可以在 Sails.js 中设置单个模型属性的 Blueprint "populate"属性吗?

node.js - 在ubuntu 17.04上安装 Node

node.js - res.redirect() 在 node.js 中不适合我

testing - PSTN调用模拟测试平台

java - response.jsonPath() 元素周围有方括号,如何检索字符串值?放心

express - 使用 Jest 测试 ExpressJS 端点