获取错误 "For async tests and hooks, ensure "done()" 被调用;"
Getting an error "For async tests and hooks, ensure "done()" is called; "
我正在尝试建立一个 MERN 网站并为其 POST 方法实施单元测试。但它给了我错误“对于异步测试和挂钩,确保调用“完成()”;” ?谁能告诉我为什么会出现此错误?以及如何解决这个问题?
错误:
- POST/产品
好的,创建一个新产品有效:
错误:超时超过 30000 毫秒。对于异步测试和挂钩,确保调用“done()”;如果返回 Promise,请确保它已解析。 (/home/nimeshaf/Documents/mernPro/MERN-project/test/api/product/post.js)
在 listOnTimeout(节点:internal/timers:557:17)
我在下面附上了我的文件
MERNProject/server.js
const express = require("express");
const mongoose = require("mongoose");
const bodyParser = require("body-parser");
const cors = require("cors");
const app = express();
//import routes
const postRoutes = require("./routes/products");
//app middleware
app.use(bodyParser.json());
app.use(cors());
app.use(postRoutes);
const PORT = 8000;
const DB_URL =
"mongodb+srv://twg:twg123@cluster0.ong7q.mongodb.net/myFirstDatabase?retryWrites=true&w=majority";
function connect() {
return new Promise((resolve, reject) => {
mongoose
.connect(DB_URL)
.then((res, err) => {
if (err) return reject(err);
//console.log(`DB connected`);
resolve();
})
.catch((err) => console.log(`DB connection error`, err));
});
}
function close() {
return mongoose.disconnect();
}
connect();
app.listen(PORT, () => {
console.log(`App is running on ${PORT}`);
});
module.exports = { connect, close };
MERNProject/test/api/products/post.js
const expect = require("chai").expect;
const request = require("supertest");
const app = require("../../../routes/products.js");
const conn = require("../../../server.js");
describe("POST /products", () => {
before((done) => {
conn
.connect()
.then(() => done())
.catch((err) => done(err));
});
after((done) => {
conn
.close()
.then(() => done())
.catch((err) => done(err));
});
it("OK, creating a new product works", (done) => {
request(app)
.post("/product/save")
.send({
productName: "Mango",
description: "description Mango",
price: "rs 50",
productCategory: "fruits",
productUrl:
"https://upload.wikimedia.org/wikipedia/commons/9/90/Hapus_Mango.jpg",
})
.then((res) => {
const body = res.body;
expect(body).to.contain.porperty("_id");
expect(body).to.contain.porperty("productName");
expect(body).to.contain.porperty("description");
expect(body).to.contain.porperty("price");
expect(body).to.contain.porperty("productCategory");
expect(body).to.contain.porperty("productUrl");
done();
});
});
});
MERNProject/routes/products.js
const express = require("express");
const Products = require("../models/products");
const router = express();
//save Products
router.post("/product/save", (err, req, res, next) => {
let newProduct = new Products(req.body);
newProduct.save((err) => {
if (err) {
return res.status(400).json({
error: err,
});
}
return res.status(200).json({
success: "Product saved successfully",
});
});
});
//get products
router.get("/products", (req, res) => {
Products.find().exec((err, products) => {
if (err) {
return res.status(400).json({
error: err,
});
}
return res.status(200).json({
success: true,
existingProducts: products,
});
});
});
//update products
router.put("/product/update/:id", (req, res) => {
Products.findByIdAndUpdate(
req.params.id,
{
$set: req.body,
},
(err, product) => {
if (err) {
return res.status(400).json({ error: err });
}
return res.status(200).json({
success: "Updated Successfully",
});
}
);
});
//delete product
router.delete("/product/delete/:id", (req, res) => {
Products.findByIdAndRemove(req.params.id).exec((err, deleteProduct) => {
if (err)
return res.status(400).json({
message: "Delete unsuccessful",
err,
});
return res.json({
message: "Delete Successfully",
deleteProduct,
});
});
});
//get specific product
router.get("/product/:id", (req, res) => {
let productId = req.params.id;
Products.findById(productId, (err, product) => {
if (err) {
return res.status(400).json({ success: false, err });
}
return res.status(200).json({
success: true,
product,
});
});
});
module.exports = router;
MERNProject/package.json
{
"name": "mern_crud",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"server": "nodemon server.js",
"client": "npm run start --prefix client",
"dev": "concurrently \"npm run server\" \"npm run client\"",
"test": "mocha --recursive --timeout 30000 --exit"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"body-parser": "^1.19.2",
"chai": "^4.3.6",
"concurrently": "^7.0.0",
"cors": "^2.8.5",
"express": "^4.17.3",
"mocha": "^9.2.2",
"mockgoose": "^8.0.4",
"mongoose": "^6.2.7",
"mongose": "^0.0.2-security",
"nodemon": "^2.0.15",
"react-router-dom": "^6.2.2",
"supertest": "^6.2.2"
}
}
您的问题可能来自规范 OK, creating a new product works
,其中 done
回调不会在承诺链失败的情况下调用。您需要添加一个 catch
:
request(app)
.post("/product/save")
.send(/* ... */)
.then((res) => {
// ...
done();
})
.catch((err) => done(err)); // this is missing
也就是说,我强烈建议使用 async/await
语法而不是 done
回调:
it("OK, creating a new product works", async () => {
const res = await request(app)
.post("/product/save")
.send(/* ... */);
const body = res.body;
expect(body).to.contain.porperty("_id");
expect(body).to.contain.porperty("productName");
expect(body).to.contain.porperty("description");
expect(body).to.contain.porperty("price");
expect(body).to.contain.porperty("productCategory");
expect(body).to.contain.porperty("productUrl");
});
我正在尝试建立一个 MERN 网站并为其 POST 方法实施单元测试。但它给了我错误“对于异步测试和挂钩,确保调用“完成()”;” ?谁能告诉我为什么会出现此错误?以及如何解决这个问题?
错误:
- POST/产品 好的,创建一个新产品有效: 错误:超时超过 30000 毫秒。对于异步测试和挂钩,确保调用“done()”;如果返回 Promise,请确保它已解析。 (/home/nimeshaf/Documents/mernPro/MERN-project/test/api/product/post.js) 在 listOnTimeout(节点:internal/timers:557:17)
我在下面附上了我的文件
MERNProject/server.js
const express = require("express");
const mongoose = require("mongoose");
const bodyParser = require("body-parser");
const cors = require("cors");
const app = express();
//import routes
const postRoutes = require("./routes/products");
//app middleware
app.use(bodyParser.json());
app.use(cors());
app.use(postRoutes);
const PORT = 8000;
const DB_URL =
"mongodb+srv://twg:twg123@cluster0.ong7q.mongodb.net/myFirstDatabase?retryWrites=true&w=majority";
function connect() {
return new Promise((resolve, reject) => {
mongoose
.connect(DB_URL)
.then((res, err) => {
if (err) return reject(err);
//console.log(`DB connected`);
resolve();
})
.catch((err) => console.log(`DB connection error`, err));
});
}
function close() {
return mongoose.disconnect();
}
connect();
app.listen(PORT, () => {
console.log(`App is running on ${PORT}`);
});
module.exports = { connect, close };
MERNProject/test/api/products/post.js
const expect = require("chai").expect;
const request = require("supertest");
const app = require("../../../routes/products.js");
const conn = require("../../../server.js");
describe("POST /products", () => {
before((done) => {
conn
.connect()
.then(() => done())
.catch((err) => done(err));
});
after((done) => {
conn
.close()
.then(() => done())
.catch((err) => done(err));
});
it("OK, creating a new product works", (done) => {
request(app)
.post("/product/save")
.send({
productName: "Mango",
description: "description Mango",
price: "rs 50",
productCategory: "fruits",
productUrl:
"https://upload.wikimedia.org/wikipedia/commons/9/90/Hapus_Mango.jpg",
})
.then((res) => {
const body = res.body;
expect(body).to.contain.porperty("_id");
expect(body).to.contain.porperty("productName");
expect(body).to.contain.porperty("description");
expect(body).to.contain.porperty("price");
expect(body).to.contain.porperty("productCategory");
expect(body).to.contain.porperty("productUrl");
done();
});
});
});
MERNProject/routes/products.js
const express = require("express");
const Products = require("../models/products");
const router = express();
//save Products
router.post("/product/save", (err, req, res, next) => {
let newProduct = new Products(req.body);
newProduct.save((err) => {
if (err) {
return res.status(400).json({
error: err,
});
}
return res.status(200).json({
success: "Product saved successfully",
});
});
});
//get products
router.get("/products", (req, res) => {
Products.find().exec((err, products) => {
if (err) {
return res.status(400).json({
error: err,
});
}
return res.status(200).json({
success: true,
existingProducts: products,
});
});
});
//update products
router.put("/product/update/:id", (req, res) => {
Products.findByIdAndUpdate(
req.params.id,
{
$set: req.body,
},
(err, product) => {
if (err) {
return res.status(400).json({ error: err });
}
return res.status(200).json({
success: "Updated Successfully",
});
}
);
});
//delete product
router.delete("/product/delete/:id", (req, res) => {
Products.findByIdAndRemove(req.params.id).exec((err, deleteProduct) => {
if (err)
return res.status(400).json({
message: "Delete unsuccessful",
err,
});
return res.json({
message: "Delete Successfully",
deleteProduct,
});
});
});
//get specific product
router.get("/product/:id", (req, res) => {
let productId = req.params.id;
Products.findById(productId, (err, product) => {
if (err) {
return res.status(400).json({ success: false, err });
}
return res.status(200).json({
success: true,
product,
});
});
});
module.exports = router;
MERNProject/package.json
{
"name": "mern_crud",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"server": "nodemon server.js",
"client": "npm run start --prefix client",
"dev": "concurrently \"npm run server\" \"npm run client\"",
"test": "mocha --recursive --timeout 30000 --exit"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"body-parser": "^1.19.2",
"chai": "^4.3.6",
"concurrently": "^7.0.0",
"cors": "^2.8.5",
"express": "^4.17.3",
"mocha": "^9.2.2",
"mockgoose": "^8.0.4",
"mongoose": "^6.2.7",
"mongose": "^0.0.2-security",
"nodemon": "^2.0.15",
"react-router-dom": "^6.2.2",
"supertest": "^6.2.2"
}
}
您的问题可能来自规范 OK, creating a new product works
,其中 done
回调不会在承诺链失败的情况下调用。您需要添加一个 catch
:
request(app)
.post("/product/save")
.send(/* ... */)
.then((res) => {
// ...
done();
})
.catch((err) => done(err)); // this is missing
也就是说,我强烈建议使用 async/await
语法而不是 done
回调:
it("OK, creating a new product works", async () => {
const res = await request(app)
.post("/product/save")
.send(/* ... */);
const body = res.body;
expect(body).to.contain.porperty("_id");
expect(body).to.contain.porperty("productName");
expect(body).to.contain.porperty("description");
expect(body).to.contain.porperty("price");
expect(body).to.contain.porperty("productCategory");
expect(body).to.contain.porperty("productUrl");
});