Node.js: Jest + redis.quit() 但打开句柄警告仍然存在
Node.js: Jest + redis.quit() but open handle warning persists
我正在尝试 运行 与 redis 和 jest 的集成测试。
当 运行 --detectOpenHandles 时总是抛出 "Jest has detected the following 1 open handle potentially keeping Jest from exiting:" 错误。
它没有挂起,所以套接字正在关闭,但我该如何编写它才不会引发警告?
我的代码
import redis from 'redis';
let red: redis.RedisClient;
beforeAll(() => {
red = redis.createClient();
});
afterAll((done) => {
red.quit(() => {
done();
});
});
test('redis', (done) => {
red.set('a', 'b', (err, data) => {
console.log(err);
red.get('a', (err, data) => {
console.log(data);
done();
});
});
});
警告
Jest has detected the following 1 open handle potentially keeping Jest from exiting:
● TCPWRAP
3 |
4 | beforeAll(() => {
> 5 | red = redis.createClient();
| ^
6 | });
7 |
8 | afterAll((done) => {
at RedisClient.Object.<anonymous>.RedisClient.create_stream (node_modules/redis/index.js:251:31)
at new RedisClient (node_modules/redis/index.js:159:10)
at Object.<anonymous>.exports.createClient (node_modules/redis/index.js:1089:12)
at Object.<anonymous>.beforeAll (src/sockets/redis.integration.test.ts:5:17)
运行 带有常规笑话的编译代码会抛出相同的警告。编译后的代码看起来几乎相同。
我也有同样的问题。我还没想出办法解决这个问题,但我有一个解决方法。
您可以添加 jest --forceExit
。
有关 forceExit 的信息:https://jestjs.io/docs/en/cli.html#forceexit
在 posting 之后想通了。我忘了post这里的答案。
它与 redis.quit()
处理其回调的方式有关。
它创建了一个新线程,因此我们需要等待整个事件循环堆栈再次循环。请参阅下面的解决方法。
async function shutdown() {
await new Promise((resolve) => {
redis.quit(() => {
resolve();
});
});
// redis.quit() creates a thread to close the connection.
// We wait until all threads have been run once to ensure the connection closes.
await new Promise(resolve => setImmediate(resolve));
}
为我修复了
const redis = require("redis");
const { promisify } = require("util");
const createRedisHelper = () => {
const client = redis.createClient(`redis://${process.env.REDIS_URI}`);
client.on("error", function (error) {
console.error(error);
});
const setAsync = promisify(client.set).bind(client);
const setCallValidateData = async (key, data) => {
return setAsync(key, JSON.stringify(data));
};
return {
setCallValidateData,
cleanCallValidateData: promisify(client.flushdb).bind(client),
end: promisify(client.end).bind(client),
};
};
module.exports = createRedisHelper;
版本:
redis 3.0.2
节点 12.6.1
我正在尝试 运行 与 redis 和 jest 的集成测试。
当 运行 --detectOpenHandles 时总是抛出 "Jest has detected the following 1 open handle potentially keeping Jest from exiting:" 错误。
它没有挂起,所以套接字正在关闭,但我该如何编写它才不会引发警告?
我的代码
import redis from 'redis';
let red: redis.RedisClient;
beforeAll(() => {
red = redis.createClient();
});
afterAll((done) => {
red.quit(() => {
done();
});
});
test('redis', (done) => {
red.set('a', 'b', (err, data) => {
console.log(err);
red.get('a', (err, data) => {
console.log(data);
done();
});
});
});
警告
Jest has detected the following 1 open handle potentially keeping Jest from exiting:
● TCPWRAP
3 |
4 | beforeAll(() => {
> 5 | red = redis.createClient();
| ^
6 | });
7 |
8 | afterAll((done) => {
at RedisClient.Object.<anonymous>.RedisClient.create_stream (node_modules/redis/index.js:251:31)
at new RedisClient (node_modules/redis/index.js:159:10)
at Object.<anonymous>.exports.createClient (node_modules/redis/index.js:1089:12)
at Object.<anonymous>.beforeAll (src/sockets/redis.integration.test.ts:5:17)
运行 带有常规笑话的编译代码会抛出相同的警告。编译后的代码看起来几乎相同。
我也有同样的问题。我还没想出办法解决这个问题,但我有一个解决方法。
您可以添加 jest --forceExit
。
有关 forceExit 的信息:https://jestjs.io/docs/en/cli.html#forceexit
在 posting 之后想通了。我忘了post这里的答案。
它与 redis.quit()
处理其回调的方式有关。
它创建了一个新线程,因此我们需要等待整个事件循环堆栈再次循环。请参阅下面的解决方法。
async function shutdown() {
await new Promise((resolve) => {
redis.quit(() => {
resolve();
});
});
// redis.quit() creates a thread to close the connection.
// We wait until all threads have been run once to ensure the connection closes.
await new Promise(resolve => setImmediate(resolve));
}
为我修复了
const redis = require("redis");
const { promisify } = require("util");
const createRedisHelper = () => {
const client = redis.createClient(`redis://${process.env.REDIS_URI}`);
client.on("error", function (error) {
console.error(error);
});
const setAsync = promisify(client.set).bind(client);
const setCallValidateData = async (key, data) => {
return setAsync(key, JSON.stringify(data));
};
return {
setCallValidateData,
cleanCallValidateData: promisify(client.flushdb).bind(client),
end: promisify(client.end).bind(client),
};
};
module.exports = createRedisHelper;
版本: redis 3.0.2 节点 12.6.1