Node.js:Jest + redis.quit()但打开的句柄警告仍然存在

13

我试图使用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运行已编译的代码会抛出相同的警告。 编译后的代码看起来几乎相同。

4个回答

20

发布之后找到了问题所在。我忘记在这里发布答案了。

问题出在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));
}

0

0
问题在于您创建了Redis客户端但没有连接,因此稍后调用redis.quit将不起作用,因为您没有连接。
尝试:

beforeAll(async () => {
    red = redis.createClient();
    await red.connect();
});


0

修复了我写的问题

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 node 12.6.1


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接