在完成测试用例之前关闭从 Deno API 返回的开放资源句柄

Close open resource handles returned from Deno APIs before finishing test case

我收到此错误消息:

Make sure to close all open resource handles returned from Deno APIs before 
finishing test case.

当我运行使用这个 Deno 测试函数时:

import { assertEquals } from "https://deno.land/std/testing/asserts.ts";

Deno.test("fetch example", async function (): Promise<void> {
    await fetch("http://www.google.com.br").then(data => {
        console.log('completed')
    });
    assertEquals("world", "world");
});

我用来运行的命令是:

deno test --allow-net

我查看了documentation,但找不到解决方法。

这是完整的错误堆栈:

$ deno test --allow-net
Compile file:///<my_path>/isolated_test.ts
running 1 tests
test fetch example ... completed
FAILED (199ms)

failures:

fetch example
AssertionError: Test case is leaking resources.
Before: {
  "0": "stdin",
  "1": "stdout",
  "2": "stderr"
}
After: {
  "0": "stdin",
  "1": "stdout",
  "2": "stderr",
  "3": "httpBody"
}

Make sure to close all open resource handles returned from Deno APIs before 
finishing test case.
    at Object.assert ($deno$/util.ts:33:11)
    at Object.resourceSanitizer [as fn] ($deno$/testing.ts:81:5)
    at async TestApi.[Symbol.asyncIterator] ($deno$/testing.ts:264:11)
    at async Object.runTests ($deno$/testing.ts:346:20)

failures:

        fetch example

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out (199ms)

我的 deno 版本

$ deno --version
deno 1.0.2
v8 8.4.300
typescript 3.9.2

Deno 测试检查在测试期间未正确关闭的资源句柄。

为了修复您的测试,您需要使用响应主体,因为内部使用资源句柄。一种简单的方法是调用 .text 或任何其他方法来消耗正文:arrayBufferjsonformDatablob

Deno.test("fetch example", async function (): Promise<void> {
    const res = await fetch("http://www.google.com.br")
    await res.text(); // Consume the body so the file handle is closed
    assertEquals("world", "world");
});

可以看到其中一个资源句柄是httpBody:

After: {
  "0": "stdin",
  "1": "stdout",
  "2": "stderr",
  "3": "httpBody"
}

目前,由于 Deno 的 fetch 不支持 AbortController.

,因此无法忽略 body

Deno 仅在状态代码为 301, 302, 303, 307, 308

之一时自动关闭资源句柄

更新

从 Deno 1.0.3 开始,Response.body 现在是 ReadableStream (PR #5787) 并且可以调用 `res.body.cancel() 关闭资源句柄;

Deno.test("fetch example", async function (): Promise<void> {
     const res = await fetch("http://www.google.com.br")
     await res.body.cancel(); // Cancel the body so the file handle is closed
     assertEquals("world", "world");
});