From 3c7546f7cd7ab5f14cdb53b7fc58b592bf07d748 Mon Sep 17 00:00:00 2001
From: Michael Kriese <michael.kriese@visualon.de>
Date: Thu, 27 May 2021 14:13:31 +0200
Subject: [PATCH] test: simplify nock handling (#10170)

---
 .../presets/bitbucket-server/index.spec.ts    |  3 -
 lib/config/presets/bitbucket/index.spec.ts    |  8 --
 lib/config/presets/gitea/index.spec.ts        |  3 -
 lib/config/presets/github/index.spec.ts       |  3 -
 lib/config/presets/gitlab/index.spec.ts       |  5 --
 lib/datasource/bitbucket-tags/index.spec.ts   |  7 --
 lib/datasource/cdnjs/index.spec.ts            |  5 --
 lib/datasource/clojure/index.spec.ts          |  2 -
 lib/datasource/crate/index.spec.ts            |  4 -
 lib/datasource/dart/index.spec.ts             |  8 --
 lib/datasource/datasource.spec.ts             |  8 --
 lib/datasource/docker/common.spec.ts          |  3 -
 lib/datasource/docker/index.spec.ts           |  2 -
 .../galaxy-collection/index.spec.ts           |  8 --
 lib/datasource/galaxy/index.spec.ts           |  8 --
 lib/datasource/github-releases/index.spec.ts  |  5 --
 lib/datasource/github-tags/index.spec.ts      | 10 ---
 lib/datasource/gitlab-tags/index.spec.ts      |  7 --
 lib/datasource/go/index.spec.ts               |  8 +-
 lib/datasource/gradle-version/index.spec.ts   |  5 --
 lib/datasource/helm/index.spec.ts             |  5 --
 lib/datasource/hex/index.spec.ts              |  2 -
 lib/datasource/jenkins-plugins/index.spec.ts  |  2 -
 lib/datasource/maven/index.spec.ts            |  2 -
 lib/datasource/npm/get.spec.ts                |  5 --
 lib/datasource/npm/index.spec.ts              |  2 -
 lib/datasource/nuget/index.spec.ts            |  5 --
 lib/datasource/orb/index.spec.ts              |  5 --
 lib/datasource/packagist/index.spec.ts        |  5 --
 lib/datasource/pod/index.spec.ts              |  5 --
 lib/datasource/pypi/index.spec.ts             |  2 -
 lib/datasource/repology/index.spec.ts         |  6 --
 lib/datasource/ruby-version/index.spec.ts     |  8 --
 lib/datasource/rubygems/index.spec.ts         |  2 -
 lib/datasource/terraform-module/index.spec.ts |  5 --
 .../__snapshots__/index.spec.ts.snap          | 35 ++++++++
 .../terraform-provider/index.spec.ts          |  8 +-
 lib/logger/err-serializer.spec.ts             |  2 -
 lib/manager/batect-wrapper/artifacts.spec.ts  |  7 +-
 lib/manager/bazel/update.spec.ts              |  5 --
 .../gradle-wrapper/artifacts-real.spec.ts     |  2 -
 lib/manager/gradle-wrapper/artifacts.spec.ts  |  2 -
 lib/manager/homebrew/update.spec.ts           |  5 --
 .../__snapshots__/index.spec.ts.snap          | 46 ++++++++++
 .../__snapshots__/parent-version.spec.ts.snap | 86 +++++++++++++++++++
 .../update/locked-dependency/index.spec.ts    | 14 +--
 .../locked-dependency/parent-version.spec.ts  | 37 +++-----
 lib/platform/bitbucket-server/index.spec.ts   |  5 --
 lib/platform/bitbucket/comments.spec.ts       |  6 --
 lib/platform/bitbucket/index.spec.ts          |  5 --
 lib/platform/bitbucket/utils.spec.ts          |  5 --
 lib/platform/gitea/gitea-helper.spec.ts       |  5 --
 lib/platform/github/index.spec.ts             |  5 --
 lib/platform/gitlab/index.spec.ts             |  5 --
 lib/util/http/bitbucket-server.spec.ts        |  7 +-
 lib/util/http/bitbucket.spec.ts               |  7 +-
 lib/util/http/gitea.spec.ts                   |  7 --
 lib/util/http/github.spec.ts                  |  2 -
 lib/util/http/gitlab.spec.ts                  |  2 -
 lib/util/http/host-rules.spec.ts              |  5 --
 lib/workers/pr/changelog/gitlab.spec.ts       |  5 +-
 lib/workers/pr/changelog/index.spec.ts        |  5 --
 .../pr/changelog/release-notes.spec.ts        |  2 -
 test/http-mock.ts                             | 46 ++++++----
 64 files changed, 222 insertions(+), 324 deletions(-)
 create mode 100644 lib/manager/npm/update/locked-dependency/__snapshots__/index.spec.ts.snap
 create mode 100644 lib/manager/npm/update/locked-dependency/__snapshots__/parent-version.spec.ts.snap

diff --git a/lib/config/presets/bitbucket-server/index.spec.ts b/lib/config/presets/bitbucket-server/index.spec.ts
index 4aaad95f33..87bae5b5d7 100644
--- a/lib/config/presets/bitbucket-server/index.spec.ts
+++ b/lib/config/presets/bitbucket-server/index.spec.ts
@@ -13,12 +13,9 @@ const basePath = '/rest/api/1.0/projects/some/repos/repo/browse';
 
 describe(getName(), () => {
   beforeEach(() => {
-    httpMock.setup();
     hostRules.find.mockReturnValue({ token: 'abc' });
   });
 
-  afterEach(() => httpMock.reset());
-
   describe('fetchJSONFile()', () => {
     it('returns JSON', async () => {
       httpMock
diff --git a/lib/config/presets/bitbucket/index.spec.ts b/lib/config/presets/bitbucket/index.spec.ts
index cf26c9410d..7a69e16f7e 100644
--- a/lib/config/presets/bitbucket/index.spec.ts
+++ b/lib/config/presets/bitbucket/index.spec.ts
@@ -14,14 +14,6 @@ describe(getName(), () => {
     setPlatformApi('bitbucket');
   });
 
-  beforeEach(() => {
-    httpMock.setup();
-  });
-
-  afterEach(() => {
-    httpMock.reset();
-  });
-
   describe('fetchJSONFile()', () => {
     it('returns JSON', async () => {
       const data = { foo: 'bar' };
diff --git a/lib/config/presets/gitea/index.spec.ts b/lib/config/presets/gitea/index.spec.ts
index 5582056521..1e706c6526 100644
--- a/lib/config/presets/gitea/index.spec.ts
+++ b/lib/config/presets/gitea/index.spec.ts
@@ -14,13 +14,10 @@ const basePath = '/repos/some/repo/contents';
 
 describe(getName(), () => {
   beforeEach(() => {
-    httpMock.setup();
     hostRules.find.mockReturnValue({ token: 'abc' });
     setBaseUrl(giteaApiHost);
   });
 
-  afterEach(() => httpMock.reset());
-
   describe('fetchJSONFile()', () => {
     it('returns JSON', async () => {
       httpMock
diff --git a/lib/config/presets/github/index.spec.ts b/lib/config/presets/github/index.spec.ts
index 9e2fffdca4..e7b45b1684 100644
--- a/lib/config/presets/github/index.spec.ts
+++ b/lib/config/presets/github/index.spec.ts
@@ -13,12 +13,9 @@ const basePath = '/repos/some/repo/contents';
 
 describe(getName(), () => {
   beforeEach(() => {
-    httpMock.setup();
     hostRules.find.mockReturnValue({ token: 'abc' });
   });
 
-  afterEach(() => httpMock.reset());
-
   describe('fetchJSONFile()', () => {
     it('returns JSON', async () => {
       httpMock
diff --git a/lib/config/presets/gitlab/index.spec.ts b/lib/config/presets/gitlab/index.spec.ts
index 53d32d88bf..b100dc70f5 100644
--- a/lib/config/presets/gitlab/index.spec.ts
+++ b/lib/config/presets/gitlab/index.spec.ts
@@ -10,11 +10,6 @@ const basePath = '/api/v4/projects/some%2Frepo/repository';
 describe(getName(), () => {
   beforeEach(() => {
     jest.resetAllMocks();
-    httpMock.setup();
-  });
-
-  afterEach(() => {
-    httpMock.reset();
   });
 
   describe('getPreset()', () => {
diff --git a/lib/datasource/bitbucket-tags/index.spec.ts b/lib/datasource/bitbucket-tags/index.spec.ts
index ab7b800cf4..83290ddd9b 100644
--- a/lib/datasource/bitbucket-tags/index.spec.ts
+++ b/lib/datasource/bitbucket-tags/index.spec.ts
@@ -4,13 +4,6 @@ import { getName } from '../../../test/util';
 import { id as datasource } from '.';
 
 describe(getName(), () => {
-  beforeEach(() => {
-    httpMock.reset();
-    httpMock.setup();
-  });
-  afterEach(() => {
-    httpMock.reset();
-  });
   describe('getReleases', () => {
     it('returns tags from bitbucket cloud', async () => {
       const body = {
diff --git a/lib/datasource/cdnjs/index.spec.ts b/lib/datasource/cdnjs/index.spec.ts
index d81e627fbc..c7aed56bcd 100644
--- a/lib/datasource/cdnjs/index.spec.ts
+++ b/lib/datasource/cdnjs/index.spec.ts
@@ -16,11 +16,6 @@ describe(getName(), () => {
   describe('getReleases', () => {
     beforeEach(() => {
       jest.clearAllMocks();
-      httpMock.setup();
-    });
-
-    afterEach(() => {
-      httpMock.reset();
     });
 
     it('throws for empty result', async () => {
diff --git a/lib/datasource/clojure/index.spec.ts b/lib/datasource/clojure/index.spec.ts
index 5285ec397c..c9c1e7ccc8 100644
--- a/lib/datasource/clojure/index.spec.ts
+++ b/lib/datasource/clojure/index.spec.ts
@@ -90,12 +90,10 @@ describe(getName(), () => {
       token: 'abc123',
     });
     jest.resetAllMocks();
-    httpMock.setup();
   });
 
   afterEach(() => {
     hostRules.clear();
-    httpMock.reset();
     delete process.env.RENOVATE_EXPERIMENTAL_NO_MAVEN_POM_CHECK;
   });
 
diff --git a/lib/datasource/crate/index.spec.ts b/lib/datasource/crate/index.spec.ts
index 00ae5986f2..b62822b12e 100644
--- a/lib/datasource/crate/index.spec.ts
+++ b/lib/datasource/crate/index.spec.ts
@@ -78,8 +78,6 @@ describe(getName(), () => {
     let adminConfig: RepoAdminConfig;
 
     beforeEach(async () => {
-      httpMock.setup();
-
       tmpDir = await dir();
 
       adminConfig = {
@@ -96,8 +94,6 @@ describe(getName(), () => {
       fs.rmdirSync(tmpDir.path, { recursive: true });
       tmpDir = null;
       setAdminConfig();
-
-      httpMock.reset();
     });
 
     it('returns null for missing registry url', async () => {
diff --git a/lib/datasource/dart/index.spec.ts b/lib/datasource/dart/index.spec.ts
index 0d14f99c40..286ac8767d 100644
--- a/lib/datasource/dart/index.spec.ts
+++ b/lib/datasource/dart/index.spec.ts
@@ -8,14 +8,6 @@ const body = loadJsonFixture('shared_preferences.json');
 const baseUrl = 'https://pub.dartlang.org/api/packages/';
 
 describe(getName(), () => {
-  beforeEach(() => {
-    httpMock.setup();
-  });
-
-  afterEach(() => {
-    httpMock.reset();
-  });
-
   describe('getReleases', () => {
     it('returns null for empty result', async () => {
       httpMock.scope(baseUrl).get('/non_sense').reply(200, null);
diff --git a/lib/datasource/datasource.spec.ts b/lib/datasource/datasource.spec.ts
index 1df40a4d1e..6a1255ff28 100644
--- a/lib/datasource/datasource.spec.ts
+++ b/lib/datasource/datasource.spec.ts
@@ -24,14 +24,6 @@ class TestDatasource extends Datasource {
 }
 
 describe(getName(), () => {
-  beforeEach(() => {
-    httpMock.setup();
-  });
-
-  afterEach(() => {
-    httpMock.reset();
-  });
-
   it('should throw on 429', async () => {
     const testDatasource = new TestDatasource();
 
diff --git a/lib/datasource/docker/common.spec.ts b/lib/datasource/docker/common.spec.ts
index 84f0729209..7bc9b260ca 100644
--- a/lib/datasource/docker/common.spec.ts
+++ b/lib/datasource/docker/common.spec.ts
@@ -1,4 +1,3 @@
-import * as httpMock from '../../../test/http-mock';
 import { getName, mocked } from '../../../test/util';
 import * as _hostRules from '../../util/host-rules';
 import * as dockerCommon from './common';
@@ -10,7 +9,6 @@ jest.mock('../../util/host-rules');
 
 describe(getName(), () => {
   beforeEach(() => {
-    httpMock.setup();
     hostRules.find.mockReturnValue({
       username: 'some-username',
       password: 'some-password',
@@ -20,7 +18,6 @@ describe(getName(), () => {
 
   afterEach(() => {
     jest.resetAllMocks();
-    httpMock.reset();
   });
 
   describe('getRegistryRepository', () => {
diff --git a/lib/datasource/docker/index.spec.ts b/lib/datasource/docker/index.spec.ts
index 2b82f07638..99b397c594 100644
--- a/lib/datasource/docker/index.spec.ts
+++ b/lib/datasource/docker/index.spec.ts
@@ -44,7 +44,6 @@ function mockEcrAuthReject(msg: string) {
 
 describe(getName(), () => {
   beforeEach(() => {
-    httpMock.setup();
     hostRules.find.mockReturnValue({
       username: 'some-username',
       password: 'some-password',
@@ -54,7 +53,6 @@ describe(getName(), () => {
 
   afterEach(() => {
     jest.resetAllMocks();
-    httpMock.reset();
   });
 
   describe('getDigest', () => {
diff --git a/lib/datasource/galaxy-collection/index.spec.ts b/lib/datasource/galaxy-collection/index.spec.ts
index 8a5725cb1d..4844b6c5ff 100644
--- a/lib/datasource/galaxy-collection/index.spec.ts
+++ b/lib/datasource/galaxy-collection/index.spec.ts
@@ -22,14 +22,6 @@ const baseUrl = 'https://galaxy.ansible.com';
 
 describe(getName(), () => {
   describe('getReleases', () => {
-    beforeEach(() => {
-      httpMock.setup();
-    });
-
-    afterEach(() => {
-      httpMock.reset();
-    });
-
     it('returns null for 404 result', async () => {
       httpMock.scope(baseUrl).get('/api/v2/collections/foo/bar/').reply(404);
       expect(
diff --git a/lib/datasource/galaxy/index.spec.ts b/lib/datasource/galaxy/index.spec.ts
index c4b16844a4..56eddd6ba3 100644
--- a/lib/datasource/galaxy/index.spec.ts
+++ b/lib/datasource/galaxy/index.spec.ts
@@ -11,14 +11,6 @@ const baseUrl = 'https://galaxy.ansible.com/';
 
 describe(getName(), () => {
   describe('getReleases', () => {
-    beforeEach(() => {
-      httpMock.setup();
-    });
-
-    afterEach(() => {
-      httpMock.reset();
-    });
-
     it('returns null for empty result', async () => {
       httpMock
         .scope(baseUrl)
diff --git a/lib/datasource/github-releases/index.spec.ts b/lib/datasource/github-releases/index.spec.ts
index 4bf1e18110..35ff90fbc9 100644
--- a/lib/datasource/github-releases/index.spec.ts
+++ b/lib/datasource/github-releases/index.spec.ts
@@ -29,11 +29,6 @@ describe(getName(), () => {
     hostRules.find.mockReturnValue({
       token: 'some-token',
     });
-    httpMock.setup();
-  });
-
-  afterEach(() => {
-    httpMock.reset();
   });
 
   describe('getReleases', () => {
diff --git a/lib/datasource/github-tags/index.spec.ts b/lib/datasource/github-tags/index.spec.ts
index cd038f8f6c..26ad50fa7a 100644
--- a/lib/datasource/github-tags/index.spec.ts
+++ b/lib/datasource/github-tags/index.spec.ts
@@ -12,17 +12,12 @@ const githubEnterpriseApiHost = 'https://git.enterprise.com';
 
 describe(getName(), () => {
   beforeEach(() => {
-    httpMock.reset();
-    httpMock.setup();
     jest.resetAllMocks();
     hostRules.hosts = jest.fn(() => []);
     hostRules.find.mockReturnValue({
       token: 'some-token',
     });
   });
-  afterEach(() => {
-    httpMock.reset();
-  });
 
   describe('getDigest', () => {
     const lookupName = 'some/dep';
@@ -110,17 +105,12 @@ describe(getName(), () => {
   });
   describe('getReleases', () => {
     beforeEach(() => {
-      httpMock.reset();
-      httpMock.setup();
       jest.resetAllMocks();
       hostRules.hosts = jest.fn(() => []);
       hostRules.find.mockReturnValue({
         token: 'some-token',
       });
     });
-    afterEach(() => {
-      httpMock.reset();
-    });
 
     const depName = 'some/dep2';
 
diff --git a/lib/datasource/gitlab-tags/index.spec.ts b/lib/datasource/gitlab-tags/index.spec.ts
index 1b106f37fa..c451a6a8b8 100644
--- a/lib/datasource/gitlab-tags/index.spec.ts
+++ b/lib/datasource/gitlab-tags/index.spec.ts
@@ -4,13 +4,6 @@ import { getName } from '../../../test/util';
 import { id as datasource } from '.';
 
 describe(getName(), () => {
-  beforeEach(() => {
-    httpMock.reset();
-    httpMock.setup();
-  });
-  afterEach(() => {
-    httpMock.reset();
-  });
   describe('getReleases', () => {
     it('returns tags from custom registry', async () => {
       const body = [
diff --git a/lib/datasource/go/index.spec.ts b/lib/datasource/go/index.spec.ts
index 0be03b9737..d5c4ea059a 100644
--- a/lib/datasource/go/index.spec.ts
+++ b/lib/datasource/go/index.spec.ts
@@ -48,13 +48,11 @@ const resGitHubEnterprise = `<!DOCTYPE html>
 
 describe(getName(), () => {
   beforeEach(() => {
-    httpMock.setup();
     hostRules.find.mockReturnValue({});
     hostRules.hosts.mockReturnValue([]);
   });
 
   afterEach(() => {
-    httpMock.reset();
     jest.resetAllMocks();
   });
 
@@ -374,7 +372,6 @@ describe(getName(), () => {
       const tags = [{ name: 'a/v1.0.0' }, { name: 'b/v2.0.0' }];
 
       for (const pkg of packages) {
-        httpMock.setup();
         httpMock
           .scope('https://api.github.com/')
           .get('/repos/x/text/tags?per_page=100')
@@ -389,7 +386,7 @@ describe(getName(), () => {
 
         const httpCalls = httpMock.getTrace();
         expect(httpCalls).toMatchSnapshot();
-        httpMock.reset();
+        httpMock.clear();
       }
     });
     it('returns none if no tags match submodules', async () => {
@@ -400,7 +397,6 @@ describe(getName(), () => {
       const tags = [{ name: 'v1.0.0' }, { name: 'v2.0.0' }];
 
       for (const pkg of packages) {
-        httpMock.setup();
         httpMock
           .scope('https://api.github.com/')
           .get('/repos/x/text/tags?per_page=100')
@@ -413,7 +409,7 @@ describe(getName(), () => {
 
         const httpCalls = httpMock.getTrace();
         expect(httpCalls).toMatchSnapshot();
-        httpMock.reset();
+        httpMock.clear();
       }
     });
     it('works for nested modules on github v2+ major upgrades', async () => {
diff --git a/lib/datasource/gradle-version/index.spec.ts b/lib/datasource/gradle-version/index.spec.ts
index 078303f6e6..a46f1f5552 100644
--- a/lib/datasource/gradle-version/index.spec.ts
+++ b/lib/datasource/gradle-version/index.spec.ts
@@ -18,11 +18,6 @@ describe(getName(), () => {
         depName: 'abc',
       };
       jest.clearAllMocks();
-      httpMock.setup();
-    });
-
-    afterEach(() => {
-      httpMock.reset();
     });
 
     it('processes real data', async () => {
diff --git a/lib/datasource/helm/index.spec.ts b/lib/datasource/helm/index.spec.ts
index ff3a14ed97..d4ed9bb425 100644
--- a/lib/datasource/helm/index.spec.ts
+++ b/lib/datasource/helm/index.spec.ts
@@ -10,11 +10,6 @@ describe(getName(), () => {
   describe('getReleases', () => {
     beforeEach(() => {
       jest.resetAllMocks();
-      httpMock.setup();
-    });
-
-    afterEach(() => {
-      httpMock.reset();
     });
 
     it('returns null if lookupName was not provided', async () => {
diff --git a/lib/datasource/hex/index.spec.ts b/lib/datasource/hex/index.spec.ts
index 739be18d1e..d6f453018a 100644
--- a/lib/datasource/hex/index.spec.ts
+++ b/lib/datasource/hex/index.spec.ts
@@ -17,12 +17,10 @@ describe(getName(), () => {
   beforeEach(() => {
     hostRules.hosts.mockReturnValue([]);
     hostRules.find.mockReturnValue({});
-    httpMock.setup();
   });
 
   afterEach(() => {
     jest.resetAllMocks();
-    httpMock.reset();
   });
 
   describe('getReleases', () => {
diff --git a/lib/datasource/jenkins-plugins/index.spec.ts b/lib/datasource/jenkins-plugins/index.spec.ts
index 0b7fa72335..8a2e7eb9a6 100644
--- a/lib/datasource/jenkins-plugins/index.spec.ts
+++ b/lib/datasource/jenkins-plugins/index.spec.ts
@@ -21,7 +21,6 @@ describe(getName(), () => {
 
     beforeEach(() => {
       resetCache();
-      httpMock.setup();
       process.env.RENOVATE_SKIP_CACHE = 'true';
       jest.resetAllMocks();
     });
@@ -30,7 +29,6 @@ describe(getName(), () => {
       if (!httpMock.allUsed()) {
         throw new Error('Not all http mocks have been used!');
       }
-      httpMock.reset();
       process.env.RENOVATE_SKIP_CACHE = SKIP_CACHE;
     });
 
diff --git a/lib/datasource/maven/index.spec.ts b/lib/datasource/maven/index.spec.ts
index 868de5c27d..ca72d31f4f 100644
--- a/lib/datasource/maven/index.spec.ts
+++ b/lib/datasource/maven/index.spec.ts
@@ -86,12 +86,10 @@ describe(getName(), () => {
       token: 'abc123',
     });
     jest.resetAllMocks();
-    httpMock.setup();
   });
 
   afterEach(() => {
     hostRules.clear();
-    httpMock.reset();
     delete process.env.RENOVATE_EXPERIMENTAL_NO_MAVEN_POM_CHECK;
   });
 
diff --git a/lib/datasource/npm/get.spec.ts b/lib/datasource/npm/get.spec.ts
index 0c444d8800..649498bfef 100644
--- a/lib/datasource/npm/get.spec.ts
+++ b/lib/datasource/npm/get.spec.ts
@@ -15,14 +15,9 @@ describe(getName(), () => {
   beforeEach(() => {
     jest.clearAllMocks();
     resetMemCache();
-    httpMock.setup();
     hostRules.clear();
   });
 
-  afterEach(() => {
-    httpMock.reset();
-  });
-
   describe('has bearer auth', () => {
     const configs = [
       `registry=https://test.org\n//test.org/:_authToken=XXX`,
diff --git a/lib/datasource/npm/index.spec.ts b/lib/datasource/npm/index.spec.ts
index 6e98e2b28d..b81d2b79c1 100644
--- a/lib/datasource/npm/index.spec.ts
+++ b/lib/datasource/npm/index.spec.ts
@@ -18,7 +18,6 @@ let npmResponse: any;
 describe(getName(), () => {
   beforeEach(() => {
     jest.resetAllMocks();
-    httpMock.setup();
     setAdminConfig();
     hostRules.clear();
     resetCache();
@@ -52,7 +51,6 @@ describe(getName(), () => {
   afterEach(() => {
     delete process.env.RENOVATE_CACHE_NPM_MINUTES;
     mockDate.reset();
-    httpMock.reset();
   });
 
   it('should return null for no versions', async () => {
diff --git a/lib/datasource/nuget/index.spec.ts b/lib/datasource/nuget/index.spec.ts
index 3ed42025a9..61091a9ccc 100644
--- a/lib/datasource/nuget/index.spec.ts
+++ b/lib/datasource/nuget/index.spec.ts
@@ -134,11 +134,6 @@ describe(getName(), () => {
       jest.resetAllMocks();
       hostRules.hosts.mockReturnValue([]);
       hostRules.find.mockReturnValue({});
-      httpMock.setup();
-    });
-
-    afterEach(() => {
-      httpMock.reset();
     });
 
     it(`can't detect nuget feed version`, async () => {
diff --git a/lib/datasource/orb/index.spec.ts b/lib/datasource/orb/index.spec.ts
index 590ba37c9a..b3d3940b3e 100644
--- a/lib/datasource/orb/index.spec.ts
+++ b/lib/datasource/orb/index.spec.ts
@@ -30,11 +30,6 @@ describe(getName(), () => {
   describe('getReleases', () => {
     beforeEach(() => {
       jest.clearAllMocks();
-      httpMock.setup();
-    });
-
-    afterEach(() => {
-      httpMock.reset();
     });
 
     it('returns null for empty result', async () => {
diff --git a/lib/datasource/packagist/index.spec.ts b/lib/datasource/packagist/index.spec.ts
index b0fc54e79a..4e7e13b990 100644
--- a/lib/datasource/packagist/index.spec.ts
+++ b/lib/datasource/packagist/index.spec.ts
@@ -21,7 +21,6 @@ describe(getName(), () => {
     let config: any;
     beforeEach(() => {
       jest.resetAllMocks();
-      httpMock.setup();
       hostRules.find = jest.fn((input) => input);
       hostRules.hosts = jest.fn(() => []);
       config = {
@@ -33,10 +32,6 @@ describe(getName(), () => {
       };
     });
 
-    afterEach(() => {
-      httpMock.reset();
-    });
-
     it('supports custom registries', async () => {
       config = {
         registryUrls: ['https://composer.renovatebot.com'],
diff --git a/lib/datasource/pod/index.spec.ts b/lib/datasource/pod/index.spec.ts
index d5a215b15c..66db34635d 100644
--- a/lib/datasource/pod/index.spec.ts
+++ b/lib/datasource/pod/index.spec.ts
@@ -19,11 +19,6 @@ describe(getName(), () => {
   describe('getReleases', () => {
     beforeEach(() => {
       jest.resetAllMocks();
-      httpMock.setup();
-    });
-
-    afterEach(() => {
-      httpMock.reset();
     });
 
     it('returns null for invalid inputs', async () => {
diff --git a/lib/datasource/pypi/index.spec.ts b/lib/datasource/pypi/index.spec.ts
index 880faa3bb0..c635b07517 100644
--- a/lib/datasource/pypi/index.spec.ts
+++ b/lib/datasource/pypi/index.spec.ts
@@ -22,13 +22,11 @@ describe(getName(), () => {
     beforeEach(() => {
       process.env = { ...OLD_ENV };
       delete process.env.PIP_INDEX_URL;
-      httpMock.setup();
       jest.resetAllMocks();
     });
 
     afterEach(() => {
       process.env = OLD_ENV;
-      httpMock.reset();
     });
 
     it('returns null for empty result', async () => {
diff --git a/lib/datasource/repology/index.spec.ts b/lib/datasource/repology/index.spec.ts
index 3e61a3675e..f984ac7bd8 100644
--- a/lib/datasource/repology/index.spec.ts
+++ b/lib/datasource/repology/index.spec.ts
@@ -54,12 +54,6 @@ const fixtureJdk = loadFixture(`openjdk.json`);
 
 describe(getName(), () => {
   describe('getReleases', () => {
-    beforeEach(() => {
-      httpMock.setup();
-    });
-
-    afterEach(() => httpMock.reset());
-
     it('returns null for empty result', async () => {
       mockResolverCall('debian_stable', 'nginx', 'binname', {
         status: 200,
diff --git a/lib/datasource/ruby-version/index.spec.ts b/lib/datasource/ruby-version/index.spec.ts
index d227fc8bf3..3efbd83d38 100644
--- a/lib/datasource/ruby-version/index.spec.ts
+++ b/lib/datasource/ruby-version/index.spec.ts
@@ -7,14 +7,6 @@ const rubyReleasesHtml = loadFixture('releases.html');
 
 describe(getName(), () => {
   describe('getReleases', () => {
-    beforeEach(() => {
-      httpMock.setup();
-    });
-
-    afterEach(() => {
-      httpMock.reset();
-    });
-
     it('parses real data', async () => {
       httpMock
         .scope('https://www.ruby-lang.org')
diff --git a/lib/datasource/rubygems/index.spec.ts b/lib/datasource/rubygems/index.spec.ts
index dce97126fb..83a07492d7 100644
--- a/lib/datasource/rubygems/index.spec.ts
+++ b/lib/datasource/rubygems/index.spec.ts
@@ -25,13 +25,11 @@ describe(getName(), () => {
 
     beforeEach(() => {
       resetCache();
-      httpMock.setup();
       process.env.RENOVATE_SKIP_CACHE = 'true';
       jest.resetAllMocks();
     });
 
     afterEach(() => {
-      httpMock.reset();
       process.env.RENOVATE_SKIP_CACHE = SKIP_CACHE;
     });
 
diff --git a/lib/datasource/terraform-module/index.spec.ts b/lib/datasource/terraform-module/index.spec.ts
index 224749e1b7..d93b9a67da 100644
--- a/lib/datasource/terraform-module/index.spec.ts
+++ b/lib/datasource/terraform-module/index.spec.ts
@@ -16,11 +16,6 @@ describe(getName(), () => {
   describe('getReleases', () => {
     beforeEach(() => {
       jest.clearAllMocks();
-      httpMock.setup();
-    });
-
-    afterEach(() => {
-      httpMock.reset();
     });
 
     it('returns null for empty result', async () => {
diff --git a/lib/datasource/terraform-provider/__snapshots__/index.spec.ts.snap b/lib/datasource/terraform-provider/__snapshots__/index.spec.ts.snap
index 600ed430ee..0f5172b44c 100644
--- a/lib/datasource/terraform-provider/__snapshots__/index.spec.ts.snap
+++ b/lib/datasource/terraform-provider/__snapshots__/index.spec.ts.snap
@@ -646,3 +646,38 @@ Array [
 `;
 
 exports[`datasource/terraform-provider/index getReleases simulate failing secondary release source 1`] = `null`;
+
+exports[`datasource/terraform-provider/index getReleases simulate failing secondary release source 2`] = `
+Array [
+  Object {
+    "headers": Object {
+      "accept": "application/json",
+      "accept-encoding": "gzip, deflate, br",
+      "host": "registry.terraform.io",
+      "user-agent": "https://github.com/renovatebot/renovate",
+    },
+    "method": "GET",
+    "url": "https://registry.terraform.io/.well-known/terraform.json",
+  },
+  Object {
+    "headers": Object {
+      "accept": "application/json",
+      "accept-encoding": "gzip, deflate, br",
+      "host": "registry.terraform.io",
+      "user-agent": "https://github.com/renovatebot/renovate",
+    },
+    "method": "GET",
+    "url": "https://registry.terraform.io/v1/providers/hashicorp/datadog",
+  },
+  Object {
+    "headers": Object {
+      "accept": "application/json",
+      "accept-encoding": "gzip, deflate, br",
+      "host": "releases.hashicorp.com",
+      "user-agent": "https://github.com/renovatebot/renovate",
+    },
+    "method": "GET",
+    "url": "https://releases.hashicorp.com/index.json",
+  },
+]
+`;
diff --git a/lib/datasource/terraform-provider/index.spec.ts b/lib/datasource/terraform-provider/index.spec.ts
index 10a5abb85e..10751814ae 100644
--- a/lib/datasource/terraform-provider/index.spec.ts
+++ b/lib/datasource/terraform-provider/index.spec.ts
@@ -14,11 +14,6 @@ describe(getName(), () => {
   describe('getReleases', () => {
     beforeEach(() => {
       jest.clearAllMocks();
-      httpMock.setup();
-    });
-
-    afterEach(() => {
-      httpMock.reset();
     });
 
     it('returns null for empty result', async () => {
@@ -127,7 +122,7 @@ describe(getName(), () => {
     it('simulate failing secondary release source', async () => {
       httpMock
         .scope(primaryUrl)
-        .get('/v1/providers/hashicorp/google-beta')
+        .get('/v1/providers/hashicorp/datadog')
         .reply(404, {
           errors: ['Not Found'],
         })
@@ -141,6 +136,7 @@ describe(getName(), () => {
       });
       expect(res).toMatchSnapshot();
       expect(res).toBeNull();
+      expect(httpMock.getTrace()).toMatchSnapshot();
     });
     it('returns null for error in service discovery', async () => {
       httpMock.scope(primaryUrl).get('/.well-known/terraform.json').reply(404);
diff --git a/lib/logger/err-serializer.spec.ts b/lib/logger/err-serializer.spec.ts
index afb2d1d65d..7864faff51 100644
--- a/lib/logger/err-serializer.spec.ts
+++ b/lib/logger/err-serializer.spec.ts
@@ -38,7 +38,6 @@ describe(getName(), () => {
     beforeEach(() => {
       // reset module
       jest.resetAllMocks();
-      httpMock.setup();
       // clean up hostRules
       hostRules.clear();
       hostRules.add({
@@ -47,7 +46,6 @@ describe(getName(), () => {
         token: 'token',
       });
     });
-    afterEach(() => httpMock.reset());
 
     it('handles http error', async () => {
       httpMock
diff --git a/lib/manager/batect-wrapper/artifacts.spec.ts b/lib/manager/batect-wrapper/artifacts.spec.ts
index 1d14f7b76f..94407ba186 100644
--- a/lib/manager/batect-wrapper/artifacts.spec.ts
+++ b/lib/manager/batect-wrapper/artifacts.spec.ts
@@ -23,8 +23,6 @@ function artifactForPath(
 
 describe(getName(), () => {
   beforeEach(() => {
-    httpMock.setup();
-
     httpMock
       .scope('https://github.com')
       .get('/batect/batect/releases/download/1.2.3/batect')
@@ -46,9 +44,8 @@ describe(getName(), () => {
       .reply(418);
   });
 
-  afterEach(() => {
-    httpMock.reset();
-  });
+  // TODO: fix mocks
+  afterEach(() => httpMock.clear(false));
 
   describe('updateArtifacts', () => {
     it('returns updated files if the wrapper script is in the root directory', async () => {
diff --git a/lib/manager/bazel/update.spec.ts b/lib/manager/bazel/update.spec.ts
index 368c092205..3be8723119 100644
--- a/lib/manager/bazel/update.spec.ts
+++ b/lib/manager/bazel/update.spec.ts
@@ -20,11 +20,6 @@ describe(getName(), () => {
   describe('updateDependency', () => {
     beforeEach(() => {
       jest.resetAllMocks();
-      httpMock.setup();
-    });
-
-    afterEach(() => {
-      httpMock.reset();
     });
 
     it('updates tag', async () => {
diff --git a/lib/manager/gradle-wrapper/artifacts-real.spec.ts b/lib/manager/gradle-wrapper/artifacts-real.spec.ts
index 3df9468491..181a332869 100644
--- a/lib/manager/gradle-wrapper/artifacts-real.spec.ts
+++ b/lib/manager/gradle-wrapper/artifacts-real.spec.ts
@@ -45,12 +45,10 @@ describe(getName(), () => {
       jest.resetAllMocks();
       await setExecConfig(adminConfig as never);
       setAdminConfig(adminConfig);
-      httpMock.setup();
     });
 
     afterEach(async () => {
       await Git(fixtures).checkout(['HEAD', '--', '.']);
-      httpMock.reset();
       setAdminConfig();
     });
 
diff --git a/lib/manager/gradle-wrapper/artifacts.spec.ts b/lib/manager/gradle-wrapper/artifacts.spec.ts
index 16f92f1dd0..ba06ec203e 100644
--- a/lib/manager/gradle-wrapper/artifacts.spec.ts
+++ b/lib/manager/gradle-wrapper/artifacts.spec.ts
@@ -49,7 +49,6 @@ function readString(...paths: string[]): Promise<string> {
 describe(getName(), () => {
   beforeEach(async () => {
     jest.resetAllMocks();
-    httpMock.setup();
 
     env.getChildProcessEnv.mockReturnValue({
       ...envMock.basic,
@@ -65,7 +64,6 @@ describe(getName(), () => {
   });
 
   afterEach(() => {
-    httpMock.reset();
     setAdminConfig();
   });
 
diff --git a/lib/manager/homebrew/update.spec.ts b/lib/manager/homebrew/update.spec.ts
index 1ffe47fabc..44b6618413 100644
--- a/lib/manager/homebrew/update.spec.ts
+++ b/lib/manager/homebrew/update.spec.ts
@@ -12,11 +12,6 @@ describe(getName(), () => {
   beforeEach(() => {
     jest.resetAllMocks();
     jest.resetModules();
-    httpMock.setup();
-  });
-
-  afterEach(() => {
-    httpMock.reset();
   });
 
   it('updates "releases" github dependency', async () => {
diff --git a/lib/manager/npm/update/locked-dependency/__snapshots__/index.spec.ts.snap b/lib/manager/npm/update/locked-dependency/__snapshots__/index.spec.ts.snap
new file mode 100644
index 0000000000..3f56c989b5
--- /dev/null
+++ b/lib/manager/npm/update/locked-dependency/__snapshots__/index.spec.ts.snap
@@ -0,0 +1,46 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`manager/npm/update/locked-dependency/index updateLockedDependency() remediates mime 1`] = `
+Array [
+  Object {
+    "headers": Object {
+      "accept": "application/json",
+      "accept-encoding": "gzip, deflate, br",
+      "host": "registry.npmjs.org",
+      "user-agent": "https://github.com/renovatebot/renovate",
+    },
+    "method": "GET",
+    "url": "https://registry.npmjs.org/mime",
+  },
+  Object {
+    "headers": Object {
+      "accept": "application/json",
+      "accept-encoding": "gzip, deflate, br",
+      "host": "registry.npmjs.org",
+      "user-agent": "https://github.com/renovatebot/renovate",
+    },
+    "method": "GET",
+    "url": "https://registry.npmjs.org/send",
+  },
+  Object {
+    "headers": Object {
+      "accept": "application/json",
+      "accept-encoding": "gzip, deflate, br",
+      "host": "registry.npmjs.org",
+      "user-agent": "https://github.com/renovatebot/renovate",
+    },
+    "method": "GET",
+    "url": "https://registry.npmjs.org/type-is",
+  },
+  Object {
+    "headers": Object {
+      "accept": "application/json",
+      "accept-encoding": "gzip, deflate, br",
+      "host": "registry.npmjs.org",
+      "user-agent": "https://github.com/renovatebot/renovate",
+    },
+    "method": "GET",
+    "url": "https://registry.npmjs.org/serve-static",
+  },
+]
+`;
diff --git a/lib/manager/npm/update/locked-dependency/__snapshots__/parent-version.spec.ts.snap b/lib/manager/npm/update/locked-dependency/__snapshots__/parent-version.spec.ts.snap
new file mode 100644
index 0000000000..02a90909a0
--- /dev/null
+++ b/lib/manager/npm/update/locked-dependency/__snapshots__/parent-version.spec.ts.snap
@@ -0,0 +1,86 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`manager/npm/update/locked-dependency/parent-version getLockedDependencies() finds indirect dependency 1`] = `
+Array [
+  Object {
+    "headers": Object {
+      "accept": "application/json",
+      "accept-encoding": "gzip, deflate, br",
+      "host": "registry.npmjs.org",
+      "user-agent": "https://github.com/renovatebot/renovate",
+    },
+    "method": "GET",
+    "url": "https://registry.npmjs.org/send",
+  },
+  Object {
+    "headers": Object {
+      "accept": "application/json",
+      "accept-encoding": "gzip, deflate, br",
+      "host": "registry.npmjs.org",
+      "user-agent": "https://github.com/renovatebot/renovate",
+    },
+    "method": "GET",
+    "url": "https://registry.npmjs.org/express",
+  },
+]
+`;
+
+exports[`manager/npm/update/locked-dependency/parent-version getLockedDependencies() finds removed dependencies 1`] = `
+Array [
+  Object {
+    "headers": Object {
+      "accept": "application/json",
+      "accept-encoding": "gzip, deflate, br",
+      "host": "registry.npmjs.org",
+      "user-agent": "https://github.com/renovatebot/renovate",
+    },
+    "method": "GET",
+    "url": "https://registry.npmjs.org/buffer-crc32",
+  },
+]
+`;
+
+exports[`manager/npm/update/locked-dependency/parent-version getLockedDependencies() finds when a greater version is needed 1`] = `
+Array [
+  Object {
+    "headers": Object {
+      "accept": "application/json",
+      "accept-encoding": "gzip, deflate, br",
+      "host": "registry.npmjs.org",
+      "user-agent": "https://github.com/renovatebot/renovate",
+    },
+    "method": "GET",
+    "url": "https://registry.npmjs.org/qs",
+  },
+]
+`;
+
+exports[`manager/npm/update/locked-dependency/parent-version getLockedDependencies() finds when a range matches greater versions 1`] = `
+Array [
+  Object {
+    "headers": Object {
+      "accept": "application/json",
+      "accept-encoding": "gzip, deflate, br",
+      "host": "registry.npmjs.org",
+      "user-agent": "https://github.com/renovatebot/renovate",
+    },
+    "method": "GET",
+    "url": "https://registry.npmjs.org/type-is",
+  },
+]
+`;
+
+exports[`manager/npm/update/locked-dependency/parent-version getLockedDependencies() returns null if no matching 1`] = `
+Array [
+  Object {
+    "headers": Object {
+      "accept": "application/json",
+      "accept-encoding": "gzip, deflate, br",
+      "host": "registry.npmjs.org",
+      "user-agent": "https://github.com/renovatebot/renovate",
+    },
+    "method": "GET",
+    "url": "https://registry.npmjs.org/debug",
+  },
+]
+`;
diff --git a/lib/manager/npm/update/locked-dependency/index.spec.ts b/lib/manager/npm/update/locked-dependency/index.spec.ts
index 8b63d485f0..36a688f6ab 100644
--- a/lib/manager/npm/update/locked-dependency/index.spec.ts
+++ b/lib/manager/npm/update/locked-dependency/index.spec.ts
@@ -17,7 +17,6 @@ describe(getName(), () => {
   describe('updateLockedDependency()', () => {
     let config: UpdateLockedConfig;
     beforeEach(() => {
-      httpMock.setup();
       config = {
         packageFile: 'package.json',
         packageFileContent,
@@ -28,9 +27,7 @@ describe(getName(), () => {
         newVersion: '1.0.1',
       };
     });
-    afterEach(() => {
-      httpMock.reset();
-    });
+
     it('validates filename', async () => {
       expect(
         await updateLockedDependency({ ...config, lockFile: 'yarn.lock' })
@@ -114,14 +111,6 @@ describe(getName(), () => {
       config.depName = 'mime';
       config.currentVersion = '1.2.11';
       config.newVersion = '1.4.1';
-      httpMock
-        .scope('https://registry.npmjs.org')
-        .get('/accepts')
-        .reply(200, acceptsJson);
-      httpMock
-        .scope('https://registry.npmjs.org')
-        .get('/express')
-        .reply(200, expressJson);
       httpMock
         .scope('https://registry.npmjs.org')
         .get('/mime')
@@ -142,6 +131,7 @@ describe(getName(), () => {
       const packageLock = JSON.parse(res['package-lock.json']);
       expect(packageLock.dependencies.mime.version).toEqual('1.4.1');
       expect(packageLock.dependencies.express.version).toEqual('4.16.0');
+      expect(httpMock.getTrace()).toMatchSnapshot();
     });
   });
 });
diff --git a/lib/manager/npm/update/locked-dependency/parent-version.spec.ts b/lib/manager/npm/update/locked-dependency/parent-version.spec.ts
index 0415965d1b..5e98013193 100644
--- a/lib/manager/npm/update/locked-dependency/parent-version.spec.ts
+++ b/lib/manager/npm/update/locked-dependency/parent-version.spec.ts
@@ -6,13 +6,6 @@ const expressJson = loadJsonFixture('express.json');
 
 describe(getName(), () => {
   describe('getLockedDependencies()', () => {
-    beforeEach(() => {
-      httpMock.setup();
-    });
-
-    afterEach(() => {
-      httpMock.reset();
-    });
     it('finds indirect dependency', async () => {
       httpMock
         .scope('https://registry.npmjs.org')
@@ -32,10 +25,13 @@ describe(getName(), () => {
         .scope('https://registry.npmjs.org')
         .get('/express')
         .reply(200, expressJson);
+
       expect(
         await findFirstParentVersion('express', '4.0.0', 'send', '0.11.1')
       ).toEqual('4.11.1');
+      expect(httpMock.getTrace()).toMatchSnapshot();
     });
+
     it('finds removed dependencies', async () => {
       httpMock
         .scope('https://registry.npmjs.org')
@@ -48,10 +44,7 @@ describe(getName(), () => {
           },
           'dist-tags': { latest: '10.0.0' },
         });
-      httpMock
-        .scope('https://registry.npmjs.org')
-        .get('/express')
-        .reply(200, expressJson);
+
       expect(
         await findFirstParentVersion(
           'express',
@@ -60,7 +53,9 @@ describe(getName(), () => {
           '10.0.0'
         )
       ).toEqual('4.9.1');
+      expect(httpMock.getTrace()).toMatchSnapshot();
     });
+
     it('finds when a greater version is needed', async () => {
       httpMock
         .scope('https://registry.npmjs.org')
@@ -75,14 +70,13 @@ describe(getName(), () => {
           },
           'dist-tags': { latest: '6.2.0' },
         });
-      httpMock
-        .scope('https://registry.npmjs.org')
-        .get('/express')
-        .reply(200, expressJson);
+
       expect(
         await findFirstParentVersion('express', '4.0.0', 'qs', '6.0.4')
       ).toEqual('4.14.0');
+      expect(httpMock.getTrace()).toMatchSnapshot();
     });
+
     it('finds when a range matches greater versions', async () => {
       httpMock
         .scope('https://registry.npmjs.org')
@@ -96,14 +90,13 @@ describe(getName(), () => {
           },
           'dist-tags': { latest: '1.6.15' },
         });
-      httpMock
-        .scope('https://registry.npmjs.org')
-        .get('/express')
-        .reply(200, expressJson);
+
       expect(
         await findFirstParentVersion('express', '4.16.1', 'type-is', '1.2.1')
       ).toEqual('4.16.1');
+      expect(httpMock.getTrace()).toMatchSnapshot();
     });
+
     it('returns null if no matching', async () => {
       httpMock
         .scope('https://registry.npmjs.org')
@@ -116,13 +109,11 @@ describe(getName(), () => {
           },
           'dist-tags': { latest: '10.0.0' },
         });
-      httpMock
-        .scope('https://registry.npmjs.org')
-        .get('/express')
-        .reply(200, expressJson);
+
       expect(
         await findFirstParentVersion('express', '4.16.1', 'debug', '9.0.0')
       ).toBeNull();
+      expect(httpMock.getTrace()).toMatchSnapshot();
     });
   });
 });
diff --git a/lib/platform/bitbucket-server/index.spec.ts b/lib/platform/bitbucket-server/index.spec.ts
index 45d6d558ff..1d5ce51901 100644
--- a/lib/platform/bitbucket-server/index.spec.ts
+++ b/lib/platform/bitbucket-server/index.spec.ts
@@ -203,8 +203,6 @@ describe(getName(), () => {
       beforeEach(async () => {
         // reset module
         jest.resetModules();
-        httpMock.reset();
-        httpMock.setup();
         jest.mock('delay');
         jest.mock('../../util/git');
         jest.mock('../../util/host-rules');
@@ -230,9 +228,6 @@ describe(getName(), () => {
           password,
         });
       });
-      afterEach(() => {
-        httpMock.reset();
-      });
 
       describe('initPlatform()', () => {
         it('should throw if no endpoint', () => {
diff --git a/lib/platform/bitbucket/comments.spec.ts b/lib/platform/bitbucket/comments.spec.ts
index 2556bdbd84..aebc255bb7 100644
--- a/lib/platform/bitbucket/comments.spec.ts
+++ b/lib/platform/bitbucket/comments.spec.ts
@@ -11,14 +11,8 @@ describe(getName(), () => {
   beforeEach(() => {
     jest.clearAllMocks();
 
-    httpMock.reset();
-    httpMock.setup();
-
     setBaseUrl(baseUrl);
   });
-  afterEach(() => {
-    httpMock.reset();
-  });
 
   describe('ensureComment()', () => {
     it('does not throw', async () => {
diff --git a/lib/platform/bitbucket/index.spec.ts b/lib/platform/bitbucket/index.spec.ts
index d024762275..29be605d92 100644
--- a/lib/platform/bitbucket/index.spec.ts
+++ b/lib/platform/bitbucket/index.spec.ts
@@ -43,8 +43,6 @@ describe(getName(), () => {
   beforeEach(async () => {
     // reset module
     jest.resetModules();
-    httpMock.reset();
-    httpMock.setup();
     jest.mock('../../util/git');
     jest.mock('../../util/host-rules');
     jest.mock('../../logger');
@@ -63,9 +61,6 @@ describe(getName(), () => {
 
     setBaseUrl(baseUrl);
   });
-  afterEach(() => {
-    httpMock.reset();
-  });
 
   async function initRepoMock(
     config?: Partial<RepoParams>,
diff --git a/lib/platform/bitbucket/utils.spec.ts b/lib/platform/bitbucket/utils.spec.ts
index ca2c34ea35..39da0c4061 100644
--- a/lib/platform/bitbucket/utils.spec.ts
+++ b/lib/platform/bitbucket/utils.spec.ts
@@ -8,14 +8,9 @@ const baseUrl = 'https://api.bitbucket.org';
 
 describe('accumulateValues()', () => {
   beforeEach(() => {
-    httpMock.setup();
     setBaseUrl(baseUrl);
   });
 
-  afterEach(() => {
-    httpMock.reset();
-  });
-
   it('paginates', async () => {
     httpMock
       .scope(baseUrl)
diff --git a/lib/platform/gitea/gitea-helper.spec.ts b/lib/platform/gitea/gitea-helper.spec.ts
index 2213effdb8..225dcc3e55 100644
--- a/lib/platform/gitea/gitea-helper.spec.ts
+++ b/lib/platform/gitea/gitea-helper.spec.ts
@@ -140,13 +140,8 @@ describe(getName(), () => {
 
   beforeEach(() => {
     jest.resetAllMocks();
-    httpMock.reset();
-    httpMock.setup();
     setBaseUrl(baseUrl);
   });
-  afterEach(() => {
-    httpMock.reset();
-  });
 
   describe('getCurrentUser', () => {
     it('should call /api/v1/user endpoint', async () => {
diff --git a/lib/platform/github/index.spec.ts b/lib/platform/github/index.spec.ts
index aa84436489..ed7d87995e 100644
--- a/lib/platform/github/index.spec.ts
+++ b/lib/platform/github/index.spec.ts
@@ -34,11 +34,6 @@ describe(getName(), () => {
     hostRules.find.mockReturnValue({
       token: 'abc123',
     });
-    httpMock.setup();
-  });
-
-  afterEach(() => {
-    httpMock.reset();
   });
 
   const graphqlOpenPullRequests = loadFixture('graphql/pullrequest-1.json');
diff --git a/lib/platform/gitlab/index.spec.ts b/lib/platform/gitlab/index.spec.ts
index a436586ac9..384d282da1 100644
--- a/lib/platform/gitlab/index.spec.ts
+++ b/lib/platform/gitlab/index.spec.ts
@@ -43,11 +43,6 @@ describe(getName(), () => {
     hostRules.find.mockReturnValue({
       token: 'abc123',
     });
-    httpMock.reset();
-    httpMock.setup();
-  });
-  afterEach(() => {
-    httpMock.reset();
   });
 
   async function initFakePlatform(version: string) {
diff --git a/lib/util/http/bitbucket-server.spec.ts b/lib/util/http/bitbucket-server.spec.ts
index f93832f00b..149f6fe182 100644
--- a/lib/util/http/bitbucket-server.spec.ts
+++ b/lib/util/http/bitbucket-server.spec.ts
@@ -22,14 +22,9 @@ describe(getName(), () => {
       token: 'token',
     });
 
-    httpMock.reset();
-    httpMock.setup();
-
     setBaseUrl(baseUrl);
   });
-  afterEach(() => {
-    httpMock.reset();
-  });
+
   it('posts', async () => {
     const body = ['a', 'b'];
     httpMock.scope(baseUrl).post('/some-url').reply(200, body);
diff --git a/lib/util/http/bitbucket.spec.ts b/lib/util/http/bitbucket.spec.ts
index 3c17426d8e..377d96387b 100644
--- a/lib/util/http/bitbucket.spec.ts
+++ b/lib/util/http/bitbucket.spec.ts
@@ -22,14 +22,9 @@ describe(getName(), () => {
       token: 'token',
     });
 
-    httpMock.reset();
-    httpMock.setup();
-
     setBaseUrl(baseUrl);
   });
-  afterEach(() => {
-    httpMock.reset();
-  });
+
   it('posts', async () => {
     const body = ['a', 'b'];
     httpMock.scope(baseUrl).post('/some-url').reply(200, body);
diff --git a/lib/util/http/gitea.spec.ts b/lib/util/http/gitea.spec.ts
index 6f28781cd9..b3043b9bc1 100644
--- a/lib/util/http/gitea.spec.ts
+++ b/lib/util/http/gitea.spec.ts
@@ -12,16 +12,9 @@ describe(getName(), () => {
 
     jest.resetAllMocks();
 
-    httpMock.reset();
-    httpMock.setup();
-
     setBaseUrl(baseUrl);
   });
 
-  afterEach(() => {
-    httpMock.reset();
-  });
-
   it('supports responses without pagination when enabled', async () => {
     httpMock
       .scope(baseUrl)
diff --git a/lib/util/http/github.spec.ts b/lib/util/http/github.spec.ts
index b1f80a7c72..23f08603a1 100644
--- a/lib/util/http/github.spec.ts
+++ b/lib/util/http/github.spec.ts
@@ -19,11 +19,9 @@ describe(getName(), () => {
     githubApi = new GithubHttp();
     setBaseUrl(githubApiHost);
     jest.resetAllMocks();
-    httpMock.setup();
   });
 
   afterEach(() => {
-    httpMock.reset();
     hostRules.clear();
   });
 
diff --git a/lib/util/http/gitlab.spec.ts b/lib/util/http/gitlab.spec.ts
index 25b03855da..d3a653f1e3 100644
--- a/lib/util/http/gitlab.spec.ts
+++ b/lib/util/http/gitlab.spec.ts
@@ -18,12 +18,10 @@ describe(getName(), () => {
   beforeEach(() => {
     gitlabApi = new GitlabHttp();
     setBaseUrl(`${gitlabApiHost}/api/v4/`);
-    httpMock.setup();
   });
 
   afterEach(() => {
     jest.resetAllMocks();
-    httpMock.reset();
   });
 
   it('paginates', async () => {
diff --git a/lib/util/http/host-rules.spec.ts b/lib/util/http/host-rules.spec.ts
index f450f61bba..46d584e6b8 100644
--- a/lib/util/http/host-rules.spec.ts
+++ b/lib/util/http/host-rules.spec.ts
@@ -1,4 +1,3 @@
-import * as httpMock from '../../../test/http-mock';
 import { getName } from '../../../test/util';
 import {
   PLATFORM_TYPE_GITEA,
@@ -38,14 +37,10 @@ describe(getName(), () => {
       authType: 'Basic',
       token: 'XXX',
     });
-
-    httpMock.reset();
-    httpMock.setup();
   });
 
   afterEach(() => {
     delete process.env.HTTP_PROXY;
-    httpMock.reset();
   });
 
   it('adds token', () => {
diff --git a/lib/workers/pr/changelog/gitlab.spec.ts b/lib/workers/pr/changelog/gitlab.spec.ts
index b629a1f8c6..1cd9a111ec 100644
--- a/lib/workers/pr/changelog/gitlab.spec.ts
+++ b/lib/workers/pr/changelog/gitlab.spec.ts
@@ -34,7 +34,6 @@ const matchHost = 'https://gitlab.com/';
 describe(getName(), () => {
   describe('getChangeLogJSON', () => {
     beforeEach(() => {
-      httpMock.setup();
       hostRules.clear();
       hostRules.add({
         hostType: PLATFORM_TYPE_GITLAB,
@@ -42,9 +41,7 @@ describe(getName(), () => {
         token: 'abc',
       });
     });
-    afterEach(() => {
-      httpMock.reset();
-    });
+
     it('returns null if @types', async () => {
       httpMock.scope(matchHost);
       expect(
diff --git a/lib/workers/pr/changelog/index.spec.ts b/lib/workers/pr/changelog/index.spec.ts
index 62a2e9e297..5b41affe66 100644
--- a/lib/workers/pr/changelog/index.spec.ts
+++ b/lib/workers/pr/changelog/index.spec.ts
@@ -34,7 +34,6 @@ const upgrade: BranchConfig = partial<BranchConfig>({
 describe(getName(), () => {
   describe('getChangeLogJSON', () => {
     beforeEach(() => {
-      httpMock.setup();
       hostRules.clear();
       hostRules.add({
         hostType: PLATFORM_TYPE_GITHUB,
@@ -43,10 +42,6 @@ describe(getName(), () => {
       });
     });
 
-    afterEach(() => {
-      httpMock.reset();
-    });
-
     it('returns null if @types', async () => {
       httpMock.scope(githubApiHost);
       expect(
diff --git a/lib/workers/pr/changelog/release-notes.spec.ts b/lib/workers/pr/changelog/release-notes.spec.ts
index 7929098c49..15b4cbba12 100644
--- a/lib/workers/pr/changelog/release-notes.spec.ts
+++ b/lib/workers/pr/changelog/release-notes.spec.ts
@@ -38,13 +38,11 @@ const gitlabTreeResponse = [
 
 describe(getName(), () => {
   beforeEach(() => {
-    httpMock.setup();
     hostRules.find.mockReturnValue({});
     hostRules.hosts.mockReturnValue([]);
   });
 
   afterEach(() => {
-    httpMock.reset();
     jest.resetAllMocks();
   });
 
diff --git a/test/http-mock.ts b/test/http-mock.ts
index 85c8718160..90a1159895 100644
--- a/test/http-mock.ts
+++ b/test/http-mock.ts
@@ -1,4 +1,5 @@
 import { Url } from 'url';
+import { afterAll, afterEach, beforeAll } from '@jest/globals';
 import is from '@sindresorhus/is';
 import { parse as parseGraphqlQuery } from 'graphql/language';
 import nock from 'nock';
@@ -95,28 +96,24 @@ function onMissing(req: TestRequest, opts?: TestRequest): void {
   }
 }
 
-export function setup(): void {
-  if (!nock.isActive()) {
-    nock.activate();
-  }
-  nock.disableNetConnect();
-  nock.emitter.on('no match', onMissing);
+export function allUsed(): boolean {
+  return nock.isDone();
 }
 
-export function reset(): void {
-  nock.emitter.removeListener('no match', onMissing);
+/**
+ *  Clear nock state. Will be called in `afterEach`
+ *  @argument throwOnPending Use `false` to simply clear mocks.
+ */
+export function clear(throwOnPending = true): void {
+  const isDone = nock.isDone();
+  const pending = nock.pendingMocks();
   nock.abortPendingRequests();
-  if (nock.isActive()) {
-    nock.restore();
-  }
   nock.cleanAll();
   requestLog = [];
   missingLog = [];
-  nock.enableNetConnect();
-}
-
-export function allUsed(): boolean {
-  return nock.isDone();
+  if (!isDone && throwOnPending) {
+    throw new Error(`Pending mocks!\n * ${pending.join('\n * ')}`);
+  }
 }
 
 export function scope(basePath: BasePath, options?: nock.Options): nock.Scope {
@@ -162,3 +159,20 @@ export function getTrace(): RequestLogItem[] /* istanbul ignore next */ {
   }
   return requestLog;
 }
+
+// init nock
+beforeAll(() => {
+  nock.emitter.on('no match', onMissing);
+  nock.disableNetConnect();
+});
+
+// clean nock to clear memory leack from http module patching
+afterAll(() => {
+  nock.emitter.removeListener('no match', onMissing);
+  nock.restore();
+});
+
+// clear nock state
+afterEach(() => {
+  clear();
+});
-- 
GitLab