Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jest --detectLeaks reports memory leaks on nock.cleanAll() and nock.restore() #2358

Open
1 of 2 tasks
jaylonez opened this issue May 24, 2022 · 9 comments
Open
1 of 2 tasks
Labels

Comments

@jaylonez
Copy link

jaylonez commented May 24, 2022

Please avoid duplicates

Reproducible test case

https://github.com/jaylonez/nock-mem-leak

Nock Version

13.2.4

Node Version

16.13.0

TypeScript Version

4.6.4

What happened?

Running a simple test with an afterAll that runs nock.cleanAll() or nock.restore() gets reported as a memory leak when using the --detectLeaks flag in jest.

Having either of these function calls present will result in the memory leak, but commenting both of them out will result in the test passing properly.

Would you be interested in contributing a fix?

  • yes
@eric-parsons
Copy link

I ran into this as well. It's not directly related to either of those functions. As long as you have a "hard" import to nock, it will cause this. For example this modified version of your sample test also triggers it for me (note the side-effect import, which is preserved in the transpiled code):

import 'nock';

describe('test', () => {
  it('can be constructed', () => {
    expect(true).toEqual(true);
  });
});

I think it has something to do with how nock monkey-patches Node's http modules which doesn't play nice with Jest's architecture. I was able to get all memory leak warnings to go away by using this workaround:

  1. Create a custom Jest environment class that extends whatever built-in environment you happen to be using (in my case jest-environment-jsdom), and configure jest to use it via testEnvironment in the Jest config. Import nock in that file, and assign it to a variable in global scope, e.g. __nock. Like so:
import { TestEnvironment } from "jest-environment-jsdom";
import nock from "nock";

export default class CustomEnvironment extends TestEnvironment {
    constructor(config, context) {
        super(config, context);
        this.global.__nock = nock;
    }
}
  1. In your tests and/or custom Jest setup, reference this global rather than importing nock. In TypeScript, you can get the correct typings by doing this: const nock = globalThis["__nock"] as typeof import("nock");

Now, assuming you call nock.cleanAll() and nock.restore() in afterAll() as you mentioned, the memory leak warning should go away. I have a large suite of tests and haven't noticed any negative side effects from this. In fact I think it contributed to speeding things up. Hope that helps.

@mkurapov
Copy link

mkurapov commented Feb 2, 2024

Adding to @eric-parsons 's solution. I noticed

    afterAll(() => {
      nock.cleanAll()
      nock.restore()
    })

would not be enough to prevent a memory leak. Sometimes it looks like there would be pending requests as well that would lead to the memory leak warning with jest. This can be avoided by adding nock.abortPendingRequests() as such:

   afterAll(() => {
     nock.cleanAll()
     nock.abortPendingRequests()
     nock.restore()
   })

@mikicho
Copy link
Contributor

mikicho commented Feb 7, 2024

@mkurapov Does this happen to you in 13.5.1? https://github.com/nock/nock/releases/tag/v13.5.1
@VladimirChuprazov fixed a memory leak.

@mkurapov
Copy link

mkurapov commented Feb 8, 2024

Hi @mikicho, yes, same with 13.5.1.
I made a simple example here: https://github.com/mkurapov/nock-memory-leak

@Uzlopak
Copy link
Member

Uzlopak commented Feb 8, 2024

@mkurapov

If I remove the nock code from the memory-leak.test.ts then jest will also report leaking memory.

@mkurapov
Copy link

mkurapov commented Feb 8, 2024

@Uzlopak that's odd. On my end:
Screenshot 2024-02-08 at 15 26 12

@VladimirChuprazov
Copy link
Contributor

VladimirChuprazov commented Feb 8, 2024

hey @mkurapov try to change the order of your imports from:

import nock from "nock";
import axios from "axios";

to:

import axios from "axios";
import nock from "nock";

@mkurapov
Copy link

@VladimirChuprazov changing the order of imports works for me in the test repo, but not in the repo where I am trying to address the leaks.

In any case, I think this can be added to the README maybe?

@mikicho
Copy link
Contributor

mikicho commented Mar 1, 2024

Maybe related to: jestjs/jest#6814

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants