Jest не завершается после успешного завершения тестов
я работаю с jest
& supertest
чтобы проверить мои конечные точки api, и тесты проходят без проблем; однако jest
никогда не выходит с сделано за X количество времени заявление, которое я обычно вижу. Я посмотрел, чтобы убедиться, что --watch
флаг не использовался и не использовался. Кажется, что соединение с сервером никогда не заканчивается так jest
остается интересно, что дальше. UserFactory.generate()
создает поддельные данные пользователя с помощью faker
библиотека.
я в недоумении, пытаясь устранить это. Я следовал рекомендуемым стратегиям на jest
страница справки без везения и копалась в трекере проблем, но ничего не видела о подобных проблемах.
это то, что я увижу при запуске моего набора тестов:
как вы можете видеть, тест выполняется 7 проходов. Мне сказали, что все тесты были выполнены, а затем morgan
показывает POST
то, что произошло. jest
никогда выходы так что на самом деле это не удается, потому что он будет тайм-аут на любом CI-сервере, запрещающем ручной выход.
я пробовал использовать .end() & done()
а также .then() & done()
вместо async/await
. Все они возвращают один и тот же конечный результат, и если бы это был вопрос обещания не решить jest
будет ошибка над неразрешенным обещанием, поэтому я в тупике, почему это не заканчивается как jest
обычно.
есть кто сталкивался с такой проблемой раньше?
пользователей.контроллер.тест.js
import mongoose from 'mongoose';
import request from 'supertest';
import { UserFactory } from '../../__mocks__';
import { User } from '../../modules';
import { config } from '../../utils';
import app from '../../';
const mockRoute = data => request(app).post(`${config.ENDPOINT}/user/sign-up`).send(data);
describe(`POST: /user/sign-up`, () => {
// remove any user data from db prior to running tests.
beforeAll(async () => { await User.remove(); });
test('Returns status 201 on success.', async () => {
// Returns the response object: res.status === { status }
const { status } = await mockRoute(UserFactory.generate());
expect(status).toEqual(201);
});
afterAll(async () => {
// drop connection to the collection
const { users } = mongoose.connection.collections;
await users.drop();
});
});
пользователь/маршруты.js
import { Router } from 'express';
import validate from 'express-validation';
import { signUp } from './controller';
import valid from './validation'
const routes = new Router();
/**
* 1. Define the route: 'user/signup'.
* 2. Validate the data being provided on the POST
* against valid.signUp object.
* 3. Provide data to signUp controller method for
* creating a user in the database.
*/
routes.post('/user/sign-up', validate(valid.signUp), signUp);
export default routes;
контроллер пользователя/.js
import HTTPStatus from 'http-status';
import User from './model';
import { config, filterBody } from '../../utils';
export const signUp = async (req, res, next) => {
const filteredBody = filterBody(req.body, config.WHITELIST.users.signUp);
try {
const user = await User.create(filteredBody);
return res.status(HTTPStatus.CREATED).json(user.toAuthJSON());
} catch (e) {
e.status = HTTPStatus.BAD_REQUEST;
return next(e);
}
}
/модель пользователей.js
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;
пользователь/проверки.js
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(),
},
},
};
middlewares.js
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]);
}
.js
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;
1 ответов
выяснил, что проблема заключалась в том, что я не делал достаточно в afterAll()
крюк.
Я сделал небольшое репо, чтобы воспроизвести проблему и устранить ее оттуда, и это было то, что нужно было сделать, чтобы 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;
}