Node.js:Jest + redis.quit() 但打开句柄警告仍然存在
Posted
技术标签:
【中文标题】Node.js:Jest + redis.quit() 但打开句柄警告仍然存在【英文标题】:Node.js: Jest + redis.quit() but open handle warning persists 【发布时间】:2019-03-27 03:10:40 【问题描述】:我正在尝试使用 redis 和 jest 运行集成测试。
使用 --detectOpenHandles 运行时,它总是抛出“Jest 检测到以下 1 个打开的句柄可能使 Jest 无法退出:”错误。
它没有挂起,所以套接字正在关闭,但我该如何编写它才不会引发该警告?
我的代码
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)
使用常规玩笑运行编译后的代码会引发相同的警告。编译后的代码看起来几乎相同。
【问题讨论】:
【参考方案1】:发帖后想通了。我忘了在这里发布答案。
这与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));
【讨论】:
【参考方案2】:我也有同样的问题。我还没有想出解决这个问题,但我有一个解决方法。
您可以添加jest --forceExit
。
有关 forceExit 的信息:https://jestjs.io/docs/en/cli.html#forceexit
【讨论】:
【参考方案3】:为我修复
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
【讨论】:
以上是关于Node.js:Jest + redis.quit() 但打开句柄警告仍然存在的主要内容,如果未能解决你的问题,请参考以下文章
Node.Js - Jest 测试(令牌问题得到 401“未授权”)
Node.js events.js: 163 throw er;使用标志 --runInBand 执行 Jest 时