用猫鼬和超级测试完成测试运行后,Jest没有退出一秒钟

问题描述

我正在从tutorial开始学习使用NodeJS和MongoDB创建RestAPI,并从它们提供的仓库中进行了更新(此帖子有很多更新),我进一步对其进行了修改,以对我的带有Jest和SuperTest的Mongo服务器。

添加我的仓库之前,我对仓库进行的主要更改是:

将侦听逻辑移动到start.js,而在package.json中将其作为主文件

start.js

const { app } = require("./index");

// Setup server port
var port = process.env.PORT || 8080;

app.listen(port,function () {
    console.log("Running RestHub on port " + port);
});

module.exports = {app};

移动逻辑后,通过导出将应用程序包装在index.js中。

index.js

app.use('/api',apiRoutes);
// Launch app to listen to specified port
// app.listen(port,function () {
//     console.log("Running RestHub on port " + port);
// });

module.exports = {app};

package.json

{
  "name": "resthub2","version": "2.0.0","description": "A Node App demonstrating simple RESTFul API implementation","main": "start.js","scripts": {
    "test": "jest","start": "node start.js"
  },"keywords": [
    "API","resful","json","node","mongodb","express"
  ],"author": "David Inyang-etoh","license": "ISC","dependencies": {
    "@shelf/jest-mongodb": "^1.2.3","body-parser": "^1.19.0","express": "^4.17.1","jest": "^26.4.2","mongoose": "^5.6.4","supertest": "^5.0.0"
  }
}

我按照特殊说明将Jest和SuperTest连接到MongoDB,并添加了这两个文件

jest.config.js

module.exports = {
  "preset": "@shelf/jest-mongodb"
};

contactController.test.js

const {MongoClient} = require('mongodb');
const {app} = require('./index'); // Link to your server file

const supertest = require('supertest');
const request = supertest(app);
const mongoose = require("mongoose");
const Contact = require("./contactModel");



describe('insert',() => {

  let connection;
  let db;

  beforeAll(async (done) => {
    connection = await MongoClient.connect(global.__MONGO_URI__,{
      useNewUrlParser: true,});
    db = await connection.db(global.__MONGO_DB_NAME__);
    Contact.deleteMany({},(err) => {
      done();
    });

  });

  afterall((done) => {

    console.log("After all?");
    // await connection.close();
    mongoose.connection.close();
    // await db.close();
    done();
  });

  it('should insert a doc into collection',async (done) => {

    try {
      const item = {};
      item["name"] = "John 3";
      item["email"] = "john@example.org";
      item["phone"] = "12345678";
      item["gender"] = "Male";

      const response2 = await request
        .post('/api/contacts')
        .send(item);
      console.log(response2.status);
      console.log("Response2 done");


      const response = await request.get("/api/contacts");
      console.log(`Weird response status is ${response.status}`);
      expect(response.status).toBe(200);
      expect(response.body.data.length).toBe(1);

      done();

    } catch (error) {
      console.log(error);
    }
  },30000);
});

但是,即使我通过所有考试(只有1),我的测试也不会终止,并且会显示以下消息

Jest did not exit one second after the test run has completed. This usually means that there are asynchronous operations that weren't stopped in your tests. Consider running Jest with `--detectOpenHandles` to troubleshoot this issue.

已经尝试过here中的大多数建议,例如runInBand,而是用猫鼬关闭了连接,但仍然没有终止。有人能解决我的问题吗?

解决方法

如果没有正在进行的异步操作并且没有打开的处理程序(如数据库连接和服务器侦听器),则不应发生此错误。这意味着每个连接都需要在afterAll的结尾处关闭。断开连接是异步操作,需要等待。

由于未导入start.js,因此不需要关闭服务器,Supertest request(app)会设置服务器并自动将其关闭。

Mongo和Mongoose API支持承诺,可以使用async..await处理。 async不应与done混合使用,因为这是一种反模式,通常会导致错误的控制流。

如果有默认的mongoose.connect连接,则需要关闭:

  afterAll(async () => {
    await mongoose.connection.close();
  });

如果存在非默认的mongoose.createConnection连接,则也需要公开和关闭它们。

Mongo连接在这里不可用,因为它不同于Mongoose连接。 Existing Mongoose default connection can be accessed for Mongo operations就像清理。如果需要Mongo(而非Mongoose)连接,则需要明确关闭它:

  afterAll(async () => {
    await connection.close();
  });

可以在单独的afterAll块中完成此操作,以使失败的操作不会影响其他操作。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...