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

Viewed 697

I'm getting this error message:

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

When I'm running this Deno testing function:

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");
});

The command I use to run it is:

deno test --allow-net

I looked at the documentation but I wasn't able to find a way to solve it.

This is the complete error stack:

$ 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)

My deno version

$ deno --version
deno 1.0.2
v8 8.4.300
typescript 3.9.2
1 Answers

Deno tests checks for resource handles that were not closed properly during a test.

In order to fix your test, you need to consume the response body, since internally uses a resource handle. A simple way would be to call .text or any other of the methods to consume the body: arrayBuffer, json, formData, blob

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");
});

You can see that one of the resource handles is httpBody:

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

Currently, there's no way to disregard the body since Deno's fetch does not support AbortController.

Deno only closes automatically the resource handle if the status code is one of 301, 302, 303, 307, 308

Update

As of Deno 1.0.3, Response.body is now a ReadableStream (PR #5787) and the resource handle can be closed calling `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");
});
Related