I'm trying to test api routes that interact with a mongodb database through mongoose. My testing tools are chai and mocha. Each time, the test fails because of a timeout error.
Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.
The route is correctly called, and the function findUserById
is also called. However, I note that findUserById
is called before the server has connected to mongodb!
How to fix this?
Here is the app file:
require("dotenv").config();
import express from "express";
import bodyParser from "body-parser";
import compression from "compression";
import cookieParser from "cookie-parser";
import rateLimit from "express-rate-limit";
import cors from "cors";
import { createServer } from "http";
import { Server } from "socket.io";
import searchRouter from "./routers/search";
import { SocketControler } from "./controllers/socket";
// Server
export const app = express();
const server = createServer(app);
const io = new Server(server);
// Middleware
app.use(cors({ credentials: true, origin: [process.env.CLIENT as string] }));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(compression());
app.use(cookieParser());
app.use(rateLimit({ max: 100})); // limit each IP to 20 requests per minute
SocketControler.manageEvents(io);
// Routers
app.use(searchRouter);
app.locals.io = io;
// Start
connectToDatabase()
.then(() =>
server.listen(process.env.PORT, () =>
console.log(`server is listening on ${process.env.PORT}!`)
)
)
.catch((err) => console.log("error", err));
The route is:
interface GetUser extends Request {
params: {
id: string;
};
}
interface IResponse extends Response {
user: UserLean;
}
const getUser = async (
req: GetUser,
res: IResponse
): Promise<IResponse> => {
try {
const user = await UserControler.findUserById(req.params.id);
return res.status(200).json({ user });
} catch (err) {
throw new Error("error.unknown");
}
};
export default getUser;
The controler function:
static findUserById(id: string) {
return UserDB.findById({ _id: id }).lean();
}
The connectToDatabase function:
import Mongoose from "mongoose";
export default async function connectToDatabase() {
try {
return Mongoose.connect(process.env.MONGODB as string, {
useFindAndModify: false,
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true,
autoIndex: false,
});
} catch (err) {
throw new Error(err);
}
}
And the test file:
import chai from "chai";
import chaiHttp from "chai-http";
import { app } from "../index";
chai.use(chaiHttp);
const api = chai.request(app).keepOpen();
describe("GET /user/:id", () => {
it("return user information", (done) => {
api
.get("/user/123")
.end((err, res) => {
chai.expect(res).to.have.status(200);
done();
});
});
});
How can I fix this?