'Jest: await mssql.connect not working (timeout)
I want to test some functionality that should not rely on mocked sql query results but that should actually write to the database in a nextjs Typescript project.
Here's a minimal example of what is going wrong:
/* @/lib/db.ts */
import sql, { ConnectionPool } from "mssql";
const sqlConfig: sql.config = {
user: process.env.DB_USER,
password: process.env.DB_PWD,
database: process.env.DB_NAME,
server: process.env.DB_HOST!,
pool: {
max: parseInt(process.env.MAX_DB_CONNECTIONS || "10"),
min: 0,
idleTimeoutMillis: 30000
},
options: {
encrypt: true, // for azure
trustServerCertificate: true // change to true for local dev / self-signed certs
}
};
if (!global.db) {
global.db = { pool: null };
}
export async function connectToDatabase(): Promise<ConnectionPool> {
if (!global.db.pool) {
console.log("No pool available, creating new pool."); // this output shows up in the console
const pool = await sql.connect(sqlConfig);
global.db.pool = pool;
console.log("Created new pool."); // this is never reached
}
return global.db.pool!;
}
/* db.test.ts */
import { connectToDatabase } from "@/lib/db";
// as you can see I already tried a high timeout. The db connection never takes this long in development
jest.setTimeout(30000);
describe("Database", ()=>{
it("can connect", async()=>{
const pool = await connectToDatabase();
expect(1).toBe(1);
});
});
export {};
The test above fails because the connectToDatabase() Promise never fulfills (it doesn't reject either, which it should do when the credentials are wrong)
I have copied the .env.local file, which contains the DB credentials, and named it .env.test. I have also verified that the env data are in fact getting read correctly by outputting sqlConfig
The db.ts functions work perfectly in development.
Is there anything I overlooked why this shouldn't work in jest out of the box?
Solution 1:[1]
Ok I found it:
After taking a deeper look at the error log, I saw that I only read the lower half (ignore the different file name from the question):
ControllingTableLock
? works (30016 ms)
? ControllingTableLock › works
ReferenceError: setImmediate is not defined
at node_modules/mssql/lib/base/connection-pool.js:402:9
at Array.forEach (<anonymous>)
at node_modules/mssql/lib/base/connection-pool.js:401:26
? ControllingTableLock › works
thrown: "Exceeded timeout of 30000 ms for a test.
Use jest.setTimeout(newTimeout) to increase the timeout value, if this is a long-running test."
5 |
6 | describe("ControllingTableLock", ()=>{
> 7 | it("works", async()=>{
| ^
8 | const pool = await connectToDatabase();
9 | expect(1).toBe(1);
10 | return;
After some research I found out that
setImmediate is not defined
is an error that stems from jest using the jsdom environment instead of node.
The fix was very simple: I added
/*
* @jest-environment node
*/
above the imports in the test file.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Taxel |
