如何使用 vitest 测试 Node-Redis 的功能?

问题描述 投票:0回答:0

我正在尝试使用

node-redis
NPM 包测试一段实现事件(即发即忘)和消息(请求-回复)模式的代码。我正在使用
vitest
来编写测试。对于使用
vitest
(事件
jest
)进行测试来说,我已经编写了一个成功的测试,但未能编写可以测试异常的测试,因此需要帮助。

我的代码最简单如下:

/*** redisCall.ts ***/

import { createClient } from 'redis';

export const redisCall = async (
    host: string,
    port: number,
    channel: string,
 export const redisCall = async (
    host: string,
    port: number,
    channel: string,
    data: Record<string, any>,
    pattern: string = 'event',
    replyChannel: string = 'replyChannel'
) => {
    let reply = null;
    let url = `redis://${host}:${port}`;

    const redisClient = createClient({ url });

    redisClient.on('error', (error) => {
        throw String(error);
    });
    await redisClient.connect();
    await redisClient.publish(channel, JSON.stringify(data));

    if (pattern === 'message') {
        const subscriber = redisClient.duplicate();
        subscriber.on('error', (error) => {
            throw String(error);
        });
        await subscriber.connect();

        const waitForReply = () =>
            new Promise(async (resolve) => {
                const listener = async (message: any) => {
                    resolve(message);
                };
                await subscriber.subscribe(replyChannel, listener);
            });
        reply = await waitForReply();
        await subscriber.unsubscribe(replyChannel);
        await subscriber.disconnect();
    }
    await redisClient.disconnect();
    return reply;
};

我的测试是:

/*** redisCall.test.ts ***/

import { afterEach, expect, vi, describe, it, test } from 'vitest';
import { createClient } from 'redis';
import { redisCall } from './redisCall.js';

const mockOn = vi.fn();
const mockConnect = vi.fn();
const mockPublish = vi.fn();
const mockDisconnect = vi.fn();
const mockUnsubscribe = vi.fn();
const mockSubscribe = vi.fn((_replyChannel, listener) => {
    setTimeout(() => {
        listener(JSON.stringify({ reply: 'This is a reply' }));
    }, 100);
});
const mockDuplicate = vi.fn(() => ({
    on: mockOn,
    connect: mockConnect,
    subscribe: mockSubscribe,
    unsubscribe: mockUnsubscribe,
    disconnect: mockDisconnect,
}));

vi.mock('redis', () => ({
    createClient: vi.fn(() => ({
        on: mockOn,
        connect: mockConnect,
        publish: mockPublish,
        disconnect: mockDisconnect,
        duplicate: mockDuplicate,
    })),
}));

afterEach(() => {
    vi.clearAllMocks();
});

test('should publish data as event', async () => {
    await redisCall('localhost', 6379, 'testChannel', { key: 'value' });
    expect(createClient).toHaveBeenCalledOnce();
    expect(createClient).toHaveBeenCalledWith({ url: 'redis://localhost:6379' });
    expect(mockConnect).toHaveBeenCalledOnce();
    expect(mockDisconnect).toHaveBeenCalledOnce();
    expect(mockOn).toHaveBeenCalledWith('error', expect.any(Function));
    expect(mockPublish).toHaveBeenCalledWith('testChannel', JSON.stringify({ key: 'value' }));
});

test('should publish data as message', async () => {
    await redisCall('localhost', 6379, 'testChannel', { key: 'value' }, 'message');
    expect(createClient).toHaveBeenCalledTimes(1);
    expect(createClient).toHaveBeenCalledWith({ url: 'redis://localhost:6379' });
    expect(mockDuplicate).toHaveBeenCalledOnce();
    expect(mockConnect).toHaveBeenCalledTimes(2);
    expect(mockDisconnect).toHaveBeenCalledTimes(2);
    expect(mockOn).toHaveBeenCalledTimes(2);
    expect(mockOn).toHaveBeenCalledWith('error', expect.any(Function));
    expect(mockPublish).toHaveBeenCalledWith('testChannel', JSON.stringify({ key: 'value' }));
    expect(mockSubscribe).toBeCalledWith('replyChannel', expect.any(Function));
    expect(mockUnsubscribe).toHaveBeenCalledOnce();
});

请任何人帮忙编写测试来测试上面

redisClient.on('error', (error) => { throw String(error);});
文件中的声明
redisCall.ts

我尝试查看 vitest 文档和 jest 文档。还查看了 stackoverflow 中错误测试的笑话示例。运气不太好。

unit-testing jestjs ts-jest node-redis vitest
© www.soinside.com 2019 - 2024. All rights reserved.