-
Notifications
You must be signed in to change notification settings - Fork 133
Open
Description
I'm trying to mock ioredis
so to be able to test it, but unfortunately, am not able to do it properly, I triedioredis-mock
but it doesnt trigger any event on ready
, so it does not work for me or I dont know how to do it properly, please someone shed some light on it
const createCacheInstance = async () => {
const address = process.env.REDIS_CLUSTER_ADDRESS
const password = process.env.REDIS_AUTH_TOKEN
logger.info(`Redis cluster env address:${address}`)
try {
if (!address || !password)
throw new Error('Environment variables {REDIS_CLUSTER_ADDRESS or REDIS_AUTH_TOKEN} are not available')
const host = address.split(':')[0]
const port = Number(address.split(':')[1])
logger.info(`Redis cluster host:${host} port:${port}`)
const tlsMode = process.env.NODE_ENV === 'production' ? { tls: {} } : {} // https://github.com/redis/ioredis?tab=readme-ov-file#special-note-aws-elasticache-clusters-with-tls
const redisCluster = new Redis.Cluster([{ host, port }], {
slotsRefreshTimeout: 2000, // to prevent [Failed to refresh slots cache error](https://github.com/redis/ioredis/issues/711)
scaleReads: 'all', // Send write queries to masters and read queries to masters or slaves randomly.
dnsLookup: (address, callback) => callback(null, address), // https://github.com/redis/ioredis?tab=readme-ov-file#special-note-aws-elasticache-clusters-with-tls
redisOptions: { password, ...tlsMode },
})
return await new Promise<{ redisCluster?: Cluster; error?: Error }>((resolve, reject) => {
redisCluster
.on('connecting', () => {
cacheStatus = redisCluster.status
logger.info('Connecting to Redis DB')
})
.on('connect', () => {
cacheStatus = redisCluster.status
logger.info('Connected to Redis DB')
})
.on('ready', () => {
cacheStatus = redisCluster.status
logger.info('Redis cache instance is ready to use')
resolve({ redisCluster })
})
.on('end', () => {
cacheStatus = redisCluster.status
logger.warn('Redis cache connection has been closed')
})
.on('error', async (error) => {
cacheStatus = redisCluster.status
cacheError = error
logger.error(error)
try {
await redisCluster.quit()
} catch (e) {
logger.error({ message: 'Error while closing the Redis cache connection', e })
}
reject({ error })
})
})
} catch (e) {
const error = e as Error
logger.error(error)
cacheStatus = 'error'
cacheError = error
return { error }
}
}
What I tried which results in "Connection is closed." "ClusterAllFailedError: Failed to refresh slots cache.
which seems I need to mock the connection itself too, but am not sure how?
import { afterAll, describe, expect, it, vi } from 'vitest'
import cacheManager, { useCache } from './index'
import { useHashTagKeyMaker } from './helper'
const mocks = vi.hoisted(() => {
return {
redisCluster: vi.fn().mockImplementation(() => ({
set: vi.fn(),
get: vi.fn(),
exists: vi.fn(),
del: vi.fn(),
sadd: vi.fn(),
smembers: vi.fn(),
srem: vi.fn(),
scard: vi.fn(),
smismember: vi.fn(),
flushdb: vi.fn(),
nodes: vi.fn().mockReturnValue([{ flushdb: vi.fn() }]),
on: vi.fn().mockImplementation((event, callback) => {
if (event === 'ready') {
callback()
}
return this
}),
quit: vi.fn(),
status: 'ready',
})),
}
})
vi.mock('ioredis', async () => {
const actual = await vi.importActual('ioredis')
return {
...actual,
Cluster: mocks.redisCluster,
}
})
Metadata
Metadata
Assignees
Labels
No labels