I have read Mock dependency in Jest with TypeScript, Typescript and Jest: Avoiding type errors on mocked functions, and many other articles on Stack Overflow, but while I can get this code working for one test, I can't get it working for two tests.
I am using ts-jest
and Postgres. I have working code to make a mock of the Pool()
constructor, and the pool instance has a query()
method that returns some mock data.
import { describe, expect, test } from "@jest/globals";
import { checkLimits } from "./db";
import { MINUTES } from "./constants";
const log = console.log;
// Make a mock for the pg Pool constructor
jest.mock("pg", () => {
return {
Pool: jest.fn(() => ({
query: jest.fn(() => {
return {
rows: [
{
timestamps: [Date.now() - 10 * MINUTES],
},
],
};
}),
})),
};
});
describe("checkLimits", () => {
test("allows reasonable usage by address", async () => {
await checkLimits("abcdef");
});
});
This code works.
What I would like to do, and have attempted to do unsuccessfully, is to be able to use mockedQuery.mockReturnValueOnce()
in my tests.
So I can do:
describe("checkLimits", () => {
test("allows reasonable usage by address", async () => {
mockedQuery.mockReturnValueOnce({
rows: [
{
timestamps: [Date.now() - 10 * MINUTES],
},
],
});
await checkLimits("abcdef");
});
test("also allows on more usage", async () => {
mockedQuery.mockReturnValueOnce({
rows: [
{
timestamps: [
Date.now() - 10 * MINUTES,
Date.now() - 3 * MINUTES,
Date.now() - 2 * MINUTES,
],
},
],
});
await checkLimits("abcdef");
});
});
However, between JS hoisting issues, ts-jest deprecations, and other complexity, I just can't seem to do it.
How can I use mockedQuery.mockReturnValueOnce()
in my mocked Postgres implementation?
Posting an answer to help others with the same issue. I wasn't able to get mockReturnValueOnce()
working, but was able to create a variable for the mock data and set that after each test.
If someone else posts an answer using mockReturnValueOnce()
I'll accept that instead. 😊
import { describe, expect, test } from "@jest/globals";
import { Row, checkLimits } from "./db";
import { Pool } from "pg";
import { MINUTES } from "./constants";
const log = console.log;
let mockRows: Array<Row> = [];
// Make a mock for the pg Pool constructor
jest.mock("pg", () => {
return {
Pool: jest.fn(() => ({
query: jest.fn(() => {
return {
rows: mockRows,
};
}),
})),
};
});
describe("checkLimits", () => {
test("is fine when there's no previous usage", async () => {
mockRows = [];
await checkLimits("some ok value");
});
test("allows reasonable usage", async () => {
mockRows = [...snip...];
await checkLimits("some ok value");
});
test("blocks unreasonable usage", async () => {
mockRows = [...snip...];
await expect(checkLimits("some bad value")).rejects.toThrow(
"some error"
);
});
});