我正在尝试使用
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 中错误测试的笑话示例。运气不太好。