Jest / NodeJS,如何为 "unhandledRejection" 构建测试

Jest / NodeJS, how to build a test for "unhandledRejection"

我正在努力实现 100% 的覆盖率。

我一直在为这部分代码创建测试:

// Manually throwing the exception will let winston handle the logging
process.on("unhandledRejection", (ex) => {
  throw ex;
});

我尝试使用以下内容:

const logger = require("../../../startup/logging");

describe("startup / logging", () => {
  it("should log the error in case of unhandledRejection", () => {
    process.emit("unhandledRejection");
    const loggerError = jest.spyOn(logger, "error");
    expect(loggerError).toHaveBeenCalled();
  });
});

但测试失败:thrown: undefined

这是logging.js的完整代码:

const { createLogger, format, transports } = require("winston");
require("winston-mongodb");
// This will forward the error in the pipeline to our error handler
require("express-async-errors");

// Manually throwing the exception will let winston handle the logging
process.on("unhandledRejection", (ex) => {
  throw ex;
});

// Log to files
const logger = createLogger({
  format: format.combine(
    format.timestamp({
      format: 'YYYY-MM-DD HH:mm:ss'
    }),
    format.errors({ stack: true }),
    format.splat(),
    format.json()
  ),
  transports: [
    new transports.File({filename: "./logs/combined.log", level: "verbose"}),
  ],
  transports: [
    new transports.File({filename: "./logs/error.log", level: "error"}),
    new transports.File({filename: "./logs/combined.log"}),
  ],
  exceptionHandlers: [
    new transports.File({ filename: "./logs/exceptions.log" }),
    new transports.File({ filename: "./logs/combined.log" }),
  ],
  handleExceptions: true,
});

// Log to database
logger.add(new transports.MongoDB({
  level: "error",
  db: "mongodb://localhost:27017/rest-api-mongodb",
  options: {
    useUnifiedTopology: true,
    useNewUrlParser: true,
  },
  metaKey: "stack",
  handleExceptions: true,
}));

module.exports = logger;

这是在 unhandledRejection 情况下触发的错误中间件:

// Winston is a logger, it allows to store errors in a log and mongoDB
const logger = require("../startup/logging");

// This function will handle all errors in the router
// It works thanks to require("express-async-errors"); that forwards the error in the pipeline

// It does not work outside of the context of express
module.exports = function (err, req, res, next) {
  logger.error(err.message, err);
  // error, warn, info, berbose, debug, silly
  res.status(500).send("Something on the server failed.");
}

感谢任何帮助!

尝试使用真正的未处理拒绝来触发 unhandledRejection。例如,调用 Promise.reject() 而不附加处理程序。

在尝试了代码之后,我让它工作如下:

require("../../../startup/logging");

describe("startup / logging", () => {
  it("should throw an error if there is an unhandledRejection", () => {
    const emitUnhandledRejection = () => process.emit("unhandledRejection");
    expect(emitUnhandledRejection).toThrow();
  });
});