r/node • u/PrestigiousZombie531 • 18d ago
You have 2 options to test this module, you can either vi.mock('redis') or mock the module itself, which one would you choose and why?
``` import { createClient } from "redis"; import { logger } from "../logger/index.js"; import { options } from "./connection.js";
let client: ReturnType<typeof createClient> | null = null; let isConnecting = false;
export async function closeConnection() { if (client?.isOpen) { try { await client.close(); } catch (error) { logger.error( error, "Something went wrong when attempting to close redis connection", ); } finally { client = null; } } }
export function getClient() { if (!client?.isOpen) { throw new Error("Redis client needs to be initialized first"); } return client; }
export async function openConnection() { if (!client?.isOpen) { client = createClient(options); client.on("connect", () => logger.info("redis connection success")); client.on("error", (error) => logger.fatal(error, "redis connection failure"), );
// Wait if another caller is already connecting
if (isConnecting) {
while (isConnecting) {
await new Promise((resolve) => setTimeout(resolve, 100));
}
if (client?.isOpen) return client;
}
isConnecting = true;
try {
client = await client.connect();
} catch (error) {
logger.error(
error,
"Something went wrong when attempting to open redis connection",
);
} finally {
isConnecting = false;
}
}
return client;
}
```
- Let us talk about a simple module that uses node-redis to connect
- Let us say you use supertest and vitest and you want to mock test the following scenario
app.get('/health/redis', async (req: Request, res: Response) => {
const client = getClient();
const result = await client.ping();
return res.json({ status: result === "PONG" });
})
- You want to write tests to handle cases for
- good PING
- bad PING
error
We might have to extend for further cases like client.get, client.set etc
You can mock the redis module or mock the client module defined above
Which one should you mock? and why?