Jestjs 测试成功完成后Jest未终止

Jestjs 测试成功完成后Jest未终止,jestjs,supertest,Jestjs,Supertest,我正在使用jest和supertest来测试我的api端点,测试顺利通过;然而,jest永远不会以我通常会看到的在X时间量内完成的语句退出。我试图确保--watch标志没有被使用,也没有被使用。似乎与服务器的连接永远不会结束,因此jest就一直在想下一步该做什么UserFactory.generate()使用faker库创建假用户数据 我无法解决这个问题。我在jest的帮助页面上遵循了推荐的策略,但运气不好,我也在问题追踪器中四处搜索,但没有看到类似的问题 以下是我将在运行测试套件时看到的内容:

我正在使用
jest
supertest
来测试我的api端点,测试顺利通过;然而,
jest
永远不会以我通常会看到的在X时间量内完成的语句退出。我试图确保
--watch
标志没有被使用,也没有被使用。似乎与服务器的连接永远不会结束,因此
jest
就一直在想下一步该做什么
UserFactory.generate()
使用
faker
库创建假用户数据

我无法解决这个问题。我在
jest
的帮助页面上遵循了推荐的策略,但运气不好,我也在问题追踪器中四处搜索,但没有看到类似的问题

以下是我将在运行测试套件时看到的内容:

afterAll(async () => {
try {
  const { todos } = mongoose.connection.collections;
  // Collection is being dropped.
  await todos.drop()
  // Connection to Mongo killed.
  await mongoose.disconnect();
  // Server connection closed.
  await server.close();
} catch (error) {
  console.log(`
    You did something wrong dummy!
    ${error}
  `);
  throw error;
}

如您所见,测试运行了7次。我被告知所有测试都已运行,然后morgan显示发生的
POST
jest
从不退出,因此实际上这是失败的,因为它将在任何CI服务器上超时,除非手动退出

我尝试使用
.end()&done()
以及
.then()&done()
来代替
异步/wait
。它们都返回了相同的最终结果,如果这是一个承诺问题,而不是解决
jest
将在未解决的承诺上出错,那么我就不明白为什么这不会像
jest
通常会终止

以前有人遇到过这样的问题吗

user.controller.test.js

user/routes.js

user/controller.js

user/model.js

user/validation.js

Middleware.js

index.js


我发现问题在于我在
afterAll()
hook中做得不够

我进行了一次小型回购,以重现问题并对其进行故障排除,这就是需要做的事情,以便
jest
能够在成功完成测试套件后退出:

afterAll(async () => {
try {
  const { todos } = mongoose.connection.collections;
  // Collection is being dropped.
  await todos.drop()
  // Connection to Mongo killed.
  await mongoose.disconnect();
  // Server connection closed.
  await server.close();
} catch (error) {
  console.log(`
    You did something wrong dummy!
    ${error}
  `);
  throw error;
}

这就是它对我的作用:

afterAll(async () => {
    try {
      // Connection to Mongo killed.
      await mongoose.disconnect();
    } catch (error) {
      console.log(`
        You did something wrong dummy!
        ${error}
      `);
      throw error;
    }
});

我还想补充一点,这里不需要
unlock()
模块。这只是一个数据库连接仍然处于打开状态的问题,并阻止
jest
使用0退出。对于我来说,执行
等待mongoose.disconnect()足够了。我没有运行
server.close()。另外,如果其他人(如我)有多个连接(使用
createConnection()
而不是
connect()
)打开),您只需要一个
mongoose.disconnect()而不是
连接1.disconnect()
连接2.disconnect()
import mongoose, { Schema } from 'mongoose';
import uniqueValidator from 'mongoose-unique-validator';
import { hashSync, compareSync } from 'bcrypt-nodejs';
import jwt from 'jsonwebtoken';

import { config } from '../../utils';

const UserSchema = new Schema({
  email: {
    type: String,
    unique: true,
    required: [true, 'Email is required!'],
    trim: true,
    validate: {
      validator(email) {
        const emailRegex = /^[-a-z0-9%S_+]+(\.[-a-z0-9%S_+]+)*@(?:[a-z0-9-]{1,63}\.){1,125}[a-z]{2,63}$/i;
        return emailRegex.test(email);
      },
      message: '{VALUE} is not a valid email!',
    }
   },
   password: {
      type: String,
      required: [true, 'Password is required!'],
      trim: true,
      minlength: [6, 'Password need to be longer!'],
      validate: {
        validator(password) {
        return password.length >= 6 && password.match(/\d+/g);
        },
      },
  }
}, { timestamps: true })

UserSchema.plugin(uniqueValidator, {
  message: '{VALUE} already taken!',
});

UserSchema.pre('save', function(next) {
  if (this.isModified('password')) {
   this.password = this._hashPassword(this.password);
   return next();
  }
  return next();
});


UserSchema.methods = {
  authenticateUser(password) {
    return compareSync(password, this.password);
  },
  _hashPassword(password) {
    return hashSync(password);
  },
  createToken() {
    return jwt.sign({ _id: this._id }, config.JWT_SECRET);
  },
  toAuthJSON() {
    return {
      _id: this._id,
      token: `JWT ${this.createToken()}`,
    };
  },
  toJSON() {
    return {
      _id: this._id,
      username: this.username,
    };
  },
};

let User;

try {
   User = mongoose.model('User');
} catch (e) {
   User = mongoose.model('User', UserSchema);
}

export default User;
import Joi from 'joi';

export default {
   signUp: {
    body: {
      email: Joi.string().email().required(),
      password: Joi.string()
        .min(6)
        .regex(/^(?=.*[0-9])(?=.*[a-zA-Z])([a-zA-Z0-9]+)$/)
        .required(),
    },
  },
};
import bodyParser from 'body-parser';
import compression from 'compression';
import cors from 'cors';
import morgan from 'morgan';
import { userRoutes } from '../modules';

export default app => {
  app.use(compression());
  app.use(bodyParser.json());
  app.use(bodyParser.urlencoded({ extended: true }));
  app.use(cors());
  app.use(morgan('dev'));
  // applying api routes last.
  app.use('/api/v1', [userRoutes]);
}
import express from 'express';
import {
  database,
  config,
  middlewares,
} from './utils';

// Create instance of Express.
const app = express();
const MODE = process.env.NODE_ENV;

// Apply middlewares to Express.
middlewares(app);
// Connect to the environment determined database.
database(config.MONGO_URI)

app.listen(config.PORT, err => {
  if (err) { return console.error(err); }
  console.log(`App running on port: ${config.PORT} in ${MODE} mode.`);
});

export default app;
afterAll(async () => {
try {
  const { todos } = mongoose.connection.collections;
  // Collection is being dropped.
  await todos.drop()
  // Connection to Mongo killed.
  await mongoose.disconnect();
  // Server connection closed.
  await server.close();
} catch (error) {
  console.log(`
    You did something wrong dummy!
    ${error}
  `);
  throw error;
}
afterAll(async () => {
    try {
      // Connection to Mongo killed.
      await mongoose.disconnect();
    } catch (error) {
      console.log(`
        You did something wrong dummy!
        ${error}
      `);
      throw error;
    }
});