【问题标题】:Node/Express Unhandled promise rejections are deprecated不推荐使用 Node/Express 未处理的承诺拒绝
【发布时间】:2019-10-13 03:41:20
【问题描述】:

我一直在尝试解决这些在我的代码中继续出现的未处理的 Promise 拒绝。

目前我得到的如下:

[nodemon] 开始 mocha --recursive -R min (node:35286) UnhandledPromiseRejectionWarning: AssertionError [ERR_ASSERTION]: The 表达式评估为假值:

断言(count + 1 === newCount)

at Driver.count.then.newCount (/Users/danale/Projects/muber/test/controllers/drivers_controller.test.js:16:13)
at processTicksAndRejections (internal/process/next_tick.js:81:5) (node:35286) UnhandledPromiseRejectionWarning: Unhandled promise

拒绝。此错误源于在异步内部抛出 没有 catch 块的函数,或者通过拒绝一个承诺 不使用 .catch() 处理。 (拒绝 ID:1)(节点:35286)[DEP0018] DeprecationWarning:不推荐使用未处理的承诺拒绝。在 未来,未处理的承诺拒绝将终止 具有非零退出代码的 Node.js 进程。

应该通过的测试是这个:

const assert = require("assert");
const request = require("supertest");
const mongoose = require("mongoose");
const app = require("../../app");

const Driver = mongoose.model("driver");

describe("Drivers controller", () => {
  it("Post to /api/drivers create a new driver", done => {
    Driver.count().then(count => {
      request(app)
        .post("api/drivers")
        .send({ email: "test@test.com" })
        .end(() => {
          Driver.count().then(newCount => {
            assert(count + 1 === newCount);
            done();
          });
        });
    });
  });
});

为了处理我之前收到的 Promise 拒绝,我这样做了:

const express = require("express");
const bodyParser = require("body-parser");
const mongoose = require("mongoose");
const routes = require("./routes/routes");
const app = express();

mongoose.Promise = global.Promise;
mongoose.connect("mongodb://localhost/muber", { useMongoClient: true });

app.use(bodyParser.json());
routes(app);

module.exports = app;

我要测试的控制器是:

const Driver = require("../models/driver");

module.exports = {
  greeting(req, res) {
    res.send({ hi: "there" });
  },

  create(req, res) {
    console.log(req.body);
    const driverProps = req.body;

    Driver.create(driverProps).then(driver => res.send(driver));
  }
};

我确实尝试像这样将catch() 添加到测试中:

describe("Drivers controller", () => {
  it("Post to /api/drivers create a new driver", done => {
    Driver.count()
      .then(count => {
        request(app)
          .post("api/drivers")
          .send({ email: "test@test.com" })
          .end((err, res) => {
            Driver.count().then(newCount => {
              assert(count + 1 === newCount);
              done();
            });
          });
      })
      .catch(error => console.log(error));
  });
});

但它没有解决错误。

这是我的路由处理程序:

const DriversController = require("../controllers/drivers_controller");

module.exports = app => {
  // Watch for incoming requests of method GET to the route http://localhost:3050/api
  app.get("/api", DriversController.greeting);

  app.post("/api/drivers", DriversController.create);
};

【问题讨论】:

  • 您是否尝试捕捉示例并将其记录在测试用例中?
  • @DoğancanArabacı,是的,我做了,我发布了我如何在上面添加catch()

标签: javascript node.js promise


【解决方案1】:

我可能是错的,但是您在进行比较和计算时没有先进行 count + 1。可以解决的问题是:

assert((count + 1) === newCount)

因此,在上面的示例中,您将计算与比较值分开。

请参阅下面的评论

【讨论】:

  • === 运算符在比较之前执行两边
【解决方案2】:

如果你正确地链接你的承诺,你将能够捕捉到错误:

describe("Drivers controller", () => {
    it("Post to /api/drivers create a new driver", () => {
        let oldCount;
        return Driver.count()
            .then(count => {
                oldCount = count;
                return new Promise((resolve, reject) => {
                    request(app)
                        .post("api/drivers")
                        .send({ email: "test@test.com" })
                        .end((err, res) => {
                            if (err) {
                                reject(err);
                            } else {
                                resolve(res);
                            }
                        });
                });
            }).then(() => {
                return Driver.count();
            }).then(newCount => {
                assert(oldCount + 1 === newCount);
            });
    });
});

在您的示例中,您在 Promise 中有 Promise,但没有返回/等待这些。如果 assert 语句抛出错误,错误不会被转发到外部 Promise。

【讨论】:

  • 用你的解决方案我仍然得到一个失败的测试:Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.
  • 你给我带来了最接近答案的答案,这让我得到了这个答案:stackoverflow.com/questions/44149096/…,它有助于在测试时解决 Promise,这个答案也有助于我理解测试就是问题所在。
  • 我已更新代码以通过向 Mocha 返回承诺来解决该问题。如果发生任何异常,mocha 实际上应该无法通过测试。这就是你不再需要 catch 子句的原因。
  • 您之前的解决方案有效。这个给了我一个拒绝的连接。测试确实失败了,谢谢你之前的解决方案,我会把那个放回去,这样它可以帮助别人。
  • 如果对api/drivers 的请求导致Connection Refused 错误,测试是否应该失败?
【解决方案3】:

为了让未来可能遇到此问题的读者更清楚,当 Mocha 测试中出现错误/不正确的断言时,promise 中会引发错误: For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves

根据corschdi重构后,我在link中添加了解决方案,这样绕过了done()回调的错误,直接带你进入问题的核心,异步测试确实失败了。

【讨论】:

    猜你喜欢
    • 2018-09-14
    • 2020-05-23
    • 1970-01-01
    • 2021-10-21
    • 1970-01-01
    • 1970-01-01
    • 2019-02-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多