4

我正在尝试在 NestJS 项目中设置 E2E 测试,但是,jest 输出如下所示:

Jest did not exit one second after the test run has completed

经过大量阅读,这是因为有一些资源尚未释放,经过一些调试后,它打开了一个到 redis 的连接,由ioredis它创建,bull由 NestJS 使用它来执行任务队列处理。问题是我在测试代码中没有对连接的引用,那么我该如何关闭它呢?afterAll我正在像这样在开玩笑的钩子中拆除 Nest 应用程序:

  afterAll(async () => {
    await app.close();
  });

但它什么也没做,连接仍然存在,开玩笑的错误消息仍然存在。我知道我可以将其添加--forceExitjest命令中,但这并不能解决任何问题,它只是将问题隐藏在地毯下。

4

2 回答 2

0

我花了一段时间才弄清楚。您需要在 afterAll 挂钩中关闭模块。我可以通过查看 nestJS Bull 存储库中的测试来找到这一点。

describe('RedisTest', () => {
  let module: TestingModule;
  beforeAll(async () => {

    module = Test.createTestingModule({
      imports: [
        BullModule.registerQueueAsync({
          name: 'test2',
        }),
      ],

    });
  });

  afterAll(async () => {
    await module.close();
  });
});

https://github.com/nestjs/bull/blob/master/e2e/module.e2e-spec.ts

于 2021-02-17T17:04:24.667 回答
0

在挣扎到几乎变得沮丧之后,我找到了一个对我有用的解决方案。
我正在使用"@nestjs/bull": "^0.3.1", "bull": "^3.21.1"
因为来自公牛包的队列使用redis,所以尽管模块和应用程序关闭,它仍保持连接打开。

    await moduleRef.close();
    await app.close();

我意识到,在--detectOpenHandles依赖leaked-handles库获取更多信息的同时使用时,您会在控制台中看到类似这样的内容:

    tcp stream {
       fd: 20,
       readable: true,
       writable: false,
       address: {},
       serverAddr: null
    }

    tcp handle leaked at one of: 
    at /media/user/somePartitionName/Workspace/Nest/project- 
    name/node_modules/ioredis/built/connectors/StandaloneConnector.js:58:45
    tcp stream {
       fd: 22,
       readable: true,
       writable: true,
       address: { address: '127.0.0.1', family: 'IPv4', port: 34876 },
       serverAddr: null
    }

解决方案 使用beforEach()&afterEach()

  • 在中beforEach(),添加此指令以获取队列的实例:
    queue = moduleRef.get(getQueueToken("queuename"));
  • afterEach(),像这样关闭队列:(也关闭你的应用程序和模块以获得更好的实践)
    await queue.close();

笔记

使用beforAll()&afterAll()不起作用并且发生同样的问题,至少从我尝试过的情况来看,两者beforEach()&afterEach()工作结合在一起。

于 2021-03-27T11:21:01.007 回答