ioredis icon indicating copy to clipboard operation
ioredis copied to clipboard

Cannot spy on `Cluster.cluster()` with jest and typescript

Open schw4rzlicht opened this issue 3 years ago • 3 comments

Hey there,

while migrating to 5.x we encountered the issue that we cannot use jest.spyOn() on Cluster.cluster() as before. These examples used to work with 4.x:

const clusterClient = new Cluster([{ host: "127.0.0.1", port: 7000 }]);

// TS2345: Argument of type 'string' is not assignable to parameter of type '[startSlotRange: number, endSlotRange: number, ...nodes: [host: string, port: number, nodeId: string, info: unknown[]][]][] | Promise[startSlotRange: number, endSlotRange: number, ...nodes: [host: string, port: number, nodeId: string, info: unknown[]][]][]>'.
jest.spyOn(clusterClient, "cluster").mockResolvedValue("cluster_state:ok");

// TS2345: Argument of type 'string' is not assignable to parameter of type '[startSlotRange: number, endSlotRange: number, ...nodes: [host: string, port: number, nodeId: string, info: unknown[]][]][] | Promise[startSlotRange: number, endSlotRange: number, ...nodes: [host: string, port: number, nodeId: string, info: unknown[]][]][]>'.
jest.spyOn(clusterClient, "cluster").mockResolvedValue("cluster_state:fail");

// TS2345: Argument of type 'null' is not assignable to parameter of type '[startSlotRange: number, endSlotRange: number, ...nodes: [host: string, port: number, nodeId: string, info: unknown[]][]][] | Promise[startSlotRange: number, endSlotRange: number, ...nodes: [host: string, port: number, nodeId: string, info: unknown[]][]][]>'.
jest.spyOn(clusterClient, "cluster").mockResolvedValue(null);

// TS2345: Argument of type 'string' is not assignable to parameter of type '[startSlotRange: number, endSlotRange: number, ...nodes: [host: string, port: number, nodeId: string, info: unknown[]][]][] | PromiseLike[startSlotRange: number, endSlotRange: number, ...nodes: [host: string, port: number, nodeId: string, info: unknown[]][]][]>'.
jest.spyOn(clusterClient, "cluster").mockImplementation(
    () =>
        new Promise((resolve) => {
            setTimeout(() => resolve("cluster_state:ok"), 2000);
        }),
);

This one still works:

jest.spyOn(clusterClient, "cluster").mockRejectedValue(new Error(message));

The tests affected will succeed as usual though if adding @ts-ignore so it must be a typing issue. Unfortunately, I am not able to fully investigate the root cause :(

schw4rzlicht avatar Apr 25 '22 22:04 schw4rzlicht

Hey @schw4rzlicht 👋

What error did you get?

luin avatar Apr 26 '22 05:04 luin

Sorry, forgot the error output, added it to the original post :)

schw4rzlicht avatar Apr 26 '22 18:04 schw4rzlicht

Thanks for the details. I think the cause is jest.spyOn doesn't work with generic methods or it's a usage issue. cluster() accepts multiple subcommand so your intention was to mock cluster('info') whereas spyOn picked cluster('slots', xxx) in your example. Haven't dug into the solution but I think it is not a ioredis specific issue.

luin avatar Apr 27 '22 02:04 luin