diff --git a/jest.config.ts b/jest.config.ts
index d354593760a4d7fda201fd004c7ed5b8f7495f09..8dfa2efa0a96357c1aa60730d2dc733119d14cda 100644
--- a/jest.config.ts
+++ b/jest.config.ts
@@ -211,7 +211,6 @@ const config: JestConfig = {
     '<rootDir>/tools/',
   ],
   cacheDirectory: '.cache/jest',
-  clearMocks: true,
   collectCoverage: true,
   coverageReporters: ci
     ? ['lcovonly', 'json']
@@ -232,6 +231,7 @@ const config: JestConfig = {
     '/__mocks__/',
   ],
   reporters: ci ? ['default', 'github-actions'] : ['default'],
+  resetMocks: true,
   setupFilesAfterEnv: [
     'jest-extended/all',
     'expect-more-jest',
diff --git a/lib/config/index.spec.ts b/lib/config/index.spec.ts
index 94e6822cf72dfc2f2a2e54548c54aa9dcf089749..9652cfaef1f66d51581c7f4309d4bf3036587862 100644
--- a/lib/config/index.spec.ts
+++ b/lib/config/index.spec.ts
@@ -2,11 +2,7 @@ import { getConfig } from './defaults';
 import { filterConfig, getManagerConfig, mergeChildConfig } from './index';
 
 jest.mock('../modules/datasource/npm');
-try {
-  jest.mock('../../config.js');
-} catch (err) {
-  // file does not exist
-}
+jest.mock('../../config.js', () => ({}), { virtual: true });
 
 const defaultConfig = getConfig();
 
diff --git a/lib/config/options/index.spec.ts b/lib/config/options/index.spec.ts
index ddfc1b2f5e91917e3bf7ca9ec3acc23a2edad7b6..20508f2684ee0a0b0918874d0a03e77b89f9822a 100644
--- a/lib/config/options/index.spec.ts
+++ b/lib/config/options/index.spec.ts
@@ -6,7 +6,7 @@ jest.unmock('../../modules/platform');
 
 describe('config/options/index', () => {
   it('test manager should have no defaultConfig', () => {
-    jest.mock('../../modules/manager', () => ({
+    jest.doMock('../../modules/manager', () => ({
       getManagers: jest.fn(() => new Map().set('testManager', {})),
     }));
 
@@ -15,7 +15,6 @@ describe('config/options/index', () => {
   });
 
   it('supportedManagers should have valid names', () => {
-    jest.unmock('../../modules/manager');
     const opts = getOptions();
     const managerList = Array.from(manager.getManagers().keys());
 
@@ -30,7 +29,6 @@ describe('config/options/index', () => {
   });
 
   it('supportedPlatforms should have valid names', () => {
-    jest.unmock('../../modules/platform');
     const opts = getOptions();
     const platformList = Array.from(platform.getPlatforms().keys());
 
diff --git a/lib/config/presets/gitea/index.spec.ts b/lib/config/presets/gitea/index.spec.ts
index 49670d27a452e3ba2cf989b4e348423aada8ca21..a84adaff4a153936d0e9635ac38eb15762cc4b7b 100644
--- a/lib/config/presets/gitea/index.spec.ts
+++ b/lib/config/presets/gitea/index.spec.ts
@@ -1,3 +1,4 @@
+import { mockDeep } from 'jest-mock-extended';
 import * as httpMock from '../../../../test/http-mock';
 import { mocked } from '../../../../test/util';
 import * as _hostRules from '../../../util/host-rules';
@@ -6,7 +7,7 @@ import { toBase64 } from '../../../util/string';
 import { PRESET_INVALID_JSON, PRESET_NOT_FOUND } from '../util';
 import * as gitea from '.';
 
-jest.mock('../../../util/host-rules');
+jest.mock('../../../util/host-rules', () => mockDeep());
 
 const hostRules = mocked(_hostRules);
 
diff --git a/lib/config/presets/github/index.spec.ts b/lib/config/presets/github/index.spec.ts
index 93ef768c1971f9526c0401a7aff62c9c5970e732..b9c06e3aa658f21a8caafe4c7f74ab59f9eb743e 100644
--- a/lib/config/presets/github/index.spec.ts
+++ b/lib/config/presets/github/index.spec.ts
@@ -1,3 +1,4 @@
+import { mockDeep } from 'jest-mock-extended';
 import * as httpMock from '../../../../test/http-mock';
 import { mocked } from '../../../../test/util';
 import * as _hostRules from '../../../util/host-rules';
@@ -5,7 +6,7 @@ import { toBase64 } from '../../../util/string';
 import { PRESET_INVALID_JSON, PRESET_NOT_FOUND } from '../util';
 import * as github from '.';
 
-jest.mock('../../../util/host-rules');
+jest.mock('../../../util/host-rules', () => mockDeep());
 
 const hostRules = mocked(_hostRules);
 
diff --git a/lib/instrumentation/decorator.spec.ts b/lib/instrumentation/decorator.spec.ts
index c18800cedf4ee8c22be3b1a3e6eff0cf3516de0c..ff812bed6fb9c7a015870294551d9f313a291f5b 100644
--- a/lib/instrumentation/decorator.spec.ts
+++ b/lib/instrumentation/decorator.spec.ts
@@ -1,4 +1,3 @@
-import { afterAll } from '@jest/globals';
 import { instrument } from './decorator';
 import { disableInstrumentations } from '.';
 
diff --git a/lib/instrumentation/index.spec.ts b/lib/instrumentation/index.spec.ts
index 82b1230e263e271c6cf728e95d4fca1fd7587b99..c098aae373dba6ffae83dcc0a5fcd29fa020b79f 100644
--- a/lib/instrumentation/index.spec.ts
+++ b/lib/instrumentation/index.spec.ts
@@ -1,4 +1,3 @@
-import { afterAll } from '@jest/globals';
 import { ProxyTracerProvider } from '@opentelemetry/api';
 import * as api from '@opentelemetry/api';
 import { NoopTracerProvider } from '@opentelemetry/api/build/src/trace/NoopTracerProvider';
diff --git a/lib/logger/__mocks__/index.ts b/lib/logger/__mocks__/index.ts
deleted file mode 100644
index 637c95b8cd85e57bcd1dbfe67842454a7594b50c..0000000000000000000000000000000000000000
--- a/lib/logger/__mocks__/index.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-const loggerLevels: string[] = [
-  'trace',
-  'debug',
-  'info',
-  'warn',
-  'error',
-  'fatal',
-  'child',
-];
-const logger: any = {};
-
-loggerLevels.forEach(k => {
-  logger[k] = jest.fn();
-});
-
-export const setContext = jest.fn();
-export const getContext = jest.fn();
-export const setMeta = jest.fn();
-export const addMeta = jest.fn();
-export const removeMeta = jest.fn();
-export const levels = jest.fn();
-export const addStream = jest.fn();
-export const getProblems = jest.fn((): any[] => []);
-
-export { logger };
diff --git a/lib/modules/datasource/docker/common.spec.ts b/lib/modules/datasource/docker/common.spec.ts
index 8414323f5521b36fe0324064528d071fbe49e14e..c30292f98b083b0815da0e907063a30fe01d5e7c 100644
--- a/lib/modules/datasource/docker/common.spec.ts
+++ b/lib/modules/datasource/docker/common.spec.ts
@@ -1,3 +1,4 @@
+import { mockDeep } from 'jest-mock-extended';
 import * as httpMock from '../../../../test/http-mock';
 import { mocked, partial } from '../../../../test/util';
 import { PAGE_NOT_FOUND_ERROR } from '../../../constants/error-messages';
@@ -16,7 +17,7 @@ const hostRules = mocked(_hostRules);
 
 const http = new Http(dockerDatasourceId);
 
-jest.mock('../../../util/host-rules');
+jest.mock('../../../util/host-rules', () => mockDeep());
 
 describe('modules/datasource/docker/common', () => {
   describe('getRegistryRepository', () => {
diff --git a/lib/modules/datasource/docker/index.spec.ts b/lib/modules/datasource/docker/index.spec.ts
index 3cf817a3aa4f95bb4a86d80565aa9b7ea6a9252e..10d3472a1c981d3f17bf774f75cff4546a787185 100644
--- a/lib/modules/datasource/docker/index.spec.ts
+++ b/lib/modules/datasource/docker/index.spec.ts
@@ -4,6 +4,7 @@ import {
   GetAuthorizationTokenCommandOutput,
 } from '@aws-sdk/client-ecr';
 import { mockClient } from 'aws-sdk-client-mock';
+import { mockDeep } from 'jest-mock-extended';
 import { getDigest, getPkgReleases } from '..';
 import { range } from '../../../../lib/util/range';
 import * as httpMock from '../../../../test/http-mock';
@@ -14,7 +15,7 @@ import { DockerDatasource } from '.';
 
 const hostRules = mocked(_hostRules);
 
-jest.mock('../../../util/host-rules');
+jest.mock('../../../util/host-rules', () => mockDeep());
 
 const ecrMock = mockClient(ECRClient);
 
diff --git a/lib/modules/datasource/github-release-attachments/index.spec.ts b/lib/modules/datasource/github-release-attachments/index.spec.ts
index 576bf7a004ff79ec75e7078f61c813d46703001f..6494eb3bc88cf8348132a91af99cb836e21e1ec3 100644
--- a/lib/modules/datasource/github-release-attachments/index.spec.ts
+++ b/lib/modules/datasource/github-release-attachments/index.spec.ts
@@ -1,3 +1,4 @@
+import { mockDeep } from 'jest-mock-extended';
 import { getDigest, getPkgReleases } from '..';
 import { mocked } from '../../../../test/util';
 import * as githubGraphql from '../../../util/github/graphql';
@@ -5,7 +6,7 @@ import * as _hostRules from '../../../util/host-rules';
 import { GitHubReleaseAttachmentMocker } from './test';
 import { GithubReleaseAttachmentsDatasource } from '.';
 
-jest.mock('../../../util/host-rules');
+jest.mock('../../../util/host-rules', () => mockDeep());
 const hostRules = mocked(_hostRules);
 
 const githubApiHost = 'https://api.github.com';
diff --git a/lib/modules/datasource/github-releases/index.spec.ts b/lib/modules/datasource/github-releases/index.spec.ts
index 42f485fa58915861ea569bf9cbedcd6394b106da..999c708fbc99f15363f6b59ae7de098b0366bc70 100644
--- a/lib/modules/datasource/github-releases/index.spec.ts
+++ b/lib/modules/datasource/github-releases/index.spec.ts
@@ -1,10 +1,11 @@
+import { mockDeep } from 'jest-mock-extended';
 import { getDigest, getPkgReleases } from '..';
 import { mocked } from '../../../../test/util';
 import * as githubGraphql from '../../../util/github/graphql';
 import * as _hostRules from '../../../util/host-rules';
 import { GithubReleasesDatasource } from '.';
 
-jest.mock('../../../util/host-rules');
+jest.mock('../../../util/host-rules', () => mockDeep());
 const hostRules = mocked(_hostRules);
 
 describe('modules/datasource/github-releases/index', () => {
diff --git a/lib/modules/datasource/github-tags/index.spec.ts b/lib/modules/datasource/github-tags/index.spec.ts
index 5f5681e432fb989b5243efaaba137189a56d4c14..8bde1f8d3fec43fe1a6fa1424c5cd881b1492ef6 100644
--- a/lib/modules/datasource/github-tags/index.spec.ts
+++ b/lib/modules/datasource/github-tags/index.spec.ts
@@ -12,7 +12,6 @@ describe('modules/datasource/github-tags/index', () => {
   const github = new GithubTagsDatasource();
 
   beforeEach(() => {
-    jest.resetAllMocks();
     jest.spyOn(hostRules, 'hosts').mockReturnValue([]);
     jest.spyOn(hostRules, 'find').mockReturnValue({
       token: 'some-token',
diff --git a/lib/modules/datasource/go/base.spec.ts b/lib/modules/datasource/go/base.spec.ts
index 68ad5bf917d361a9a3414e0a45ae6d67336a0d2c..b5c85a49870fe5ca7f8ced24178f1449d26b3754 100644
--- a/lib/modules/datasource/go/base.spec.ts
+++ b/lib/modules/datasource/go/base.spec.ts
@@ -1,3 +1,4 @@
+import { mockDeep } from 'jest-mock-extended';
 import { Fixtures } from '../../../../test/fixtures';
 import * as httpMock from '../../../../test/http-mock';
 import { mocked } from '../../../../test/util';
@@ -7,7 +8,7 @@ import { GithubTagsDatasource } from '../github-tags';
 import { GitlabTagsDatasource } from '../gitlab-tags';
 import { BaseGoDatasource } from './base';
 
-jest.mock('../../../util/host-rules');
+jest.mock('../../../util/host-rules', () => mockDeep());
 
 const hostRules = mocked(_hostRules);
 
@@ -30,15 +31,10 @@ describe('modules/datasource/go/base', () => {
 
   describe('go-get requests', () => {
     beforeEach(() => {
-      jest.resetAllMocks();
       hostRules.find.mockReturnValue({});
       hostRules.hosts.mockReturnValue([]);
     });
 
-    afterEach(() => {
-      jest.resetAllMocks();
-    });
-
     describe('meta name=go-source', () => {
       it('returns null for unknown prefix', async () => {
         const meta =
diff --git a/lib/modules/datasource/go/index.spec.ts b/lib/modules/datasource/go/index.spec.ts
index ab23fe6909d00b8e1a1f8cead6b2db043a8ac7de..b836ff8805808f75b7a4669bb4346162be656ac8 100644
--- a/lib/modules/datasource/go/index.spec.ts
+++ b/lib/modules/datasource/go/index.spec.ts
@@ -1,10 +1,11 @@
+import { mockDeep } from 'jest-mock-extended';
 import { Fixtures } from '../../../../test/fixtures';
 import * as httpMock from '../../../../test/http-mock';
 import { mocked } from '../../../../test/util';
 import * as _hostRules from '../../../util/host-rules';
 import { GoDatasource } from '.';
 
-jest.mock('../../../util/host-rules');
+jest.mock('../../../util/host-rules', () => mockDeep());
 const hostRules = mocked(_hostRules);
 
 const getReleasesDirectMock = jest.fn();
@@ -70,15 +71,10 @@ describe('modules/datasource/go/index', () => {
 
   describe('getDigest', () => {
     beforeEach(() => {
-      jest.resetAllMocks();
       hostRules.find.mockReturnValue({});
       hostRules.hosts.mockReturnValue([]);
     });
 
-    afterEach(() => {
-      jest.resetAllMocks();
-    });
-
     it('returns null for no go-source tag', async () => {
       httpMock
         .scope('https://golang.org/')
diff --git a/lib/modules/datasource/go/releases-direct.spec.ts b/lib/modules/datasource/go/releases-direct.spec.ts
index 27debf62018adb1c574c68123a16b9f30bee71d7..fa83dd4655ef4df1430597875a4eb036e45e3e15 100644
--- a/lib/modules/datasource/go/releases-direct.spec.ts
+++ b/lib/modules/datasource/go/releases-direct.spec.ts
@@ -1,3 +1,4 @@
+import { mockDeep } from 'jest-mock-extended';
 import * as httpMock from '../../../../test/http-mock';
 import { mocked } from '../../../../test/util';
 import * as _hostRules from '../../../util/host-rules';
@@ -6,7 +7,7 @@ import { GithubTagsDatasource } from '../github-tags';
 import { BaseGoDatasource } from './base';
 import { GoDirectDatasource } from './releases-direct';
 
-jest.mock('../../../util/host-rules');
+jest.mock('../../../util/host-rules', () => mockDeep());
 jest.mock('./base');
 
 const datasource = new GoDirectDatasource();
diff --git a/lib/modules/datasource/helm/index.spec.ts b/lib/modules/datasource/helm/index.spec.ts
index b737d4cd92aaeb2c9ba14a96133f0a5da9c05ddd..93366c38bcb4b10c2c2ac68b943a7087c53e78f4 100644
--- a/lib/modules/datasource/helm/index.spec.ts
+++ b/lib/modules/datasource/helm/index.spec.ts
@@ -9,10 +9,6 @@ const indexYaml = Fixtures.get('index.yaml');
 
 describe('modules/datasource/helm/index', () => {
   describe('getReleases', () => {
-    beforeEach(() => {
-      jest.resetAllMocks();
-    });
-
     it('returns null if packageName was not provided', async () => {
       expect(
         await getPkgReleases({
diff --git a/lib/modules/datasource/hex/index.spec.ts b/lib/modules/datasource/hex/index.spec.ts
index 609220fc7a50550286417bbe347056fcdb466744..96f435c6b88204c0c543e850ec1d77597fe61a53 100644
--- a/lib/modules/datasource/hex/index.spec.ts
+++ b/lib/modules/datasource/hex/index.spec.ts
@@ -1,3 +1,4 @@
+import { mockDeep } from 'jest-mock-extended';
 import { getPkgReleases } from '..';
 import { Fixtures } from '../../../../test/fixtures';
 import * as httpMock from '../../../../test/http-mock';
@@ -8,7 +9,7 @@ import { HexDatasource } from '.';
 const certifiResponse = Fixtures.get('certifi.json');
 const privatePackageResponse = Fixtures.get('private_package.json');
 
-jest.mock('../../../util/host-rules');
+jest.mock('../../../util/host-rules', () => mockDeep());
 
 const baseUrl = 'https://hex.pm/api';
 const datasource = HexDatasource.id;
@@ -19,10 +20,6 @@ describe('modules/datasource/hex/index', () => {
     hostRules.find.mockReturnValue({});
   });
 
-  afterEach(() => {
-    jest.resetAllMocks();
-  });
-
   describe('getReleases', () => {
     it('returns null for empty result', async () => {
       httpMock.scope(baseUrl).get('/packages/non_existent_package').reply(200);
diff --git a/lib/modules/datasource/maven/index.spec.ts b/lib/modules/datasource/maven/index.spec.ts
index 0366e8b408d331d80468109eee879c5633f771df..fd29186ced119424647e5a9fadb326e075332d4c 100644
--- a/lib/modules/datasource/maven/index.spec.ts
+++ b/lib/modules/datasource/maven/index.spec.ts
@@ -176,7 +176,6 @@ describe('modules/datasource/maven/index', () => {
       matchHost: 'custom.registry.renovatebot.com',
       token: '123test',
     });
-    jest.resetAllMocks();
   });
 
   afterEach(() => {
diff --git a/lib/modules/datasource/maven/s3.spec.ts b/lib/modules/datasource/maven/s3.spec.ts
index 61a8534cedd034d674c1ff9aea7501589b511213..a73c29a17c944e5e381c2e1ca1e73814dead25de 100644
--- a/lib/modules/datasource/maven/s3.spec.ts
+++ b/lib/modules/datasource/maven/s3.spec.ts
@@ -36,7 +36,6 @@ describe('modules/datasource/maven/s3', () => {
       matchHost: 'custom.registry.renovatebot.com',
       token: '123test',
     });
-    jest.resetAllMocks();
   });
 
   afterEach(() => {
diff --git a/lib/modules/datasource/npm/index.spec.ts b/lib/modules/datasource/npm/index.spec.ts
index 54a37ed1603abdc31f06171e1b5464e2982d2118..ed71b13b93f1d9b322368fd9beb88e676df4f18c 100644
--- a/lib/modules/datasource/npm/index.spec.ts
+++ b/lib/modules/datasource/npm/index.spec.ts
@@ -11,7 +11,6 @@ let npmResponse: any;
 
 describe('modules/datasource/npm/index', () => {
   beforeEach(() => {
-    jest.resetAllMocks();
     GlobalConfig.reset();
     hostRules.clear();
     setNpmrc();
diff --git a/lib/modules/datasource/npm/npmrc.spec.ts b/lib/modules/datasource/npm/npmrc.spec.ts
index 912badedad51e152ec8eee605b6383f963a029fc..3b9c4f381c1e1a3287e26315e3c7bd1b31bbcee0 100644
--- a/lib/modules/datasource/npm/npmrc.spec.ts
+++ b/lib/modules/datasource/npm/npmrc.spec.ts
@@ -16,7 +16,6 @@ describe('modules/datasource/npm/npmrc', () => {
   beforeEach(() => {
     setNpmrc('');
     GlobalConfig.reset();
-    jest.resetAllMocks();
   });
 
   describe('getMatchHostFromNpmrcHost()', () => {
diff --git a/lib/modules/datasource/nuget/index.spec.ts b/lib/modules/datasource/nuget/index.spec.ts
index 43e38f25ee56a8eb517e1c0efd52a86e771e0275..b0b56b29ec276a3631457819d3b7bb11b12cfee7 100644
--- a/lib/modules/datasource/nuget/index.spec.ts
+++ b/lib/modules/datasource/nuget/index.spec.ts
@@ -1,3 +1,4 @@
+import { mockDeep } from 'jest-mock-extended';
 import { getPkgReleases } from '..';
 import { Fixtures } from '../../../../test/fixtures';
 import * as httpMock from '../../../../test/http-mock';
@@ -10,7 +11,7 @@ const datasource = NugetDatasource.id;
 
 const hostRules: any = _hostRules;
 
-jest.mock('../../../util/host-rules');
+jest.mock('../../../util/host-rules', () => mockDeep());
 
 const pkgInfoV3FromNuget = Fixtures.get('nunit/v3_nuget_org.xml');
 const pkgListV3Registration = Fixtures.get('nunit/v3_registration.json');
@@ -95,10 +96,6 @@ const configV3Multiple = {
 
 describe('modules/datasource/nuget/index', () => {
   describe('parseRegistryUrl', () => {
-    beforeEach(() => {
-      jest.resetAllMocks();
-    });
-
     it('extracts feed version from registry URL hash (v3)', () => {
       const parsed = parseRegistryUrl('https://my-registry#protocolVersion=3');
 
@@ -130,7 +127,6 @@ describe('modules/datasource/nuget/index', () => {
 
   describe('getReleases', () => {
     beforeEach(() => {
-      jest.resetAllMocks();
       hostRules.hosts.mockReturnValue([]);
       hostRules.find.mockReturnValue({});
     });
diff --git a/lib/modules/datasource/packagist/index.spec.ts b/lib/modules/datasource/packagist/index.spec.ts
index 9f973a86053fed4e96fcfbfa50f71cd835a82556..e445de1790fb52c5819592291236201f9945f40d 100644
--- a/lib/modules/datasource/packagist/index.spec.ts
+++ b/lib/modules/datasource/packagist/index.spec.ts
@@ -1,3 +1,4 @@
+import { mockDeep } from 'jest-mock-extended';
 import { getPkgReleases } from '..';
 import { Fixtures } from '../../../../test/fixtures';
 import * as httpMock from '../../../../test/http-mock';
@@ -7,7 +8,7 @@ import * as composerVersioning from '../../versioning/composer';
 import { id as versioning } from '../../versioning/loose';
 import { PackagistDatasource } from '.';
 
-jest.mock('../../../util/host-rules');
+jest.mock('../../../util/host-rules', () => mockDeep());
 
 const hostRules = _hostRules;
 
@@ -24,7 +25,6 @@ describe('modules/datasource/packagist/index', () => {
     let config: any;
 
     beforeEach(() => {
-      jest.resetAllMocks();
       hostRules.find = jest.fn((input: HostRule) => input);
       hostRules.hosts = jest.fn(() => []);
       config = {
diff --git a/lib/modules/datasource/pod/index.spec.ts b/lib/modules/datasource/pod/index.spec.ts
index 9ac7b8c9af0b80a702bbdf3450df1b4f20b1b3d7..366cd0886ebb5c129c075ad5659b7272fc3e34c3 100644
--- a/lib/modules/datasource/pod/index.spec.ts
+++ b/lib/modules/datasource/pod/index.spec.ts
@@ -20,7 +20,6 @@ const cocoapodsHost = 'https://cdn.cocoapods.org';
 describe('modules/datasource/pod/index', () => {
   describe('getReleases', () => {
     beforeEach(() => {
-      jest.resetAllMocks();
       hostRules.clear();
     });
 
diff --git a/lib/modules/datasource/pypi/index.spec.ts b/lib/modules/datasource/pypi/index.spec.ts
index 7e2df584b795c9f3958eede4f1a3b4a0a257a0c8..1627305641296d59b18b996d73d40efecf96c688 100644
--- a/lib/modules/datasource/pypi/index.spec.ts
+++ b/lib/modules/datasource/pypi/index.spec.ts
@@ -26,7 +26,6 @@ describe('modules/datasource/pypi/index', () => {
     beforeEach(() => {
       process.env = { ...OLD_ENV };
       delete process.env.PIP_INDEX_URL;
-      jest.resetAllMocks();
     });
 
     afterEach(() => {
diff --git a/lib/modules/datasource/rubygems/index.spec.ts b/lib/modules/datasource/rubygems/index.spec.ts
index 3db344a1a14c488631c7fc3ee644026d4db5c5a9..942ced25dbcdf62ed46ffe89ebddecad481e1df9 100644
--- a/lib/modules/datasource/rubygems/index.spec.ts
+++ b/lib/modules/datasource/rubygems/index.spec.ts
@@ -19,7 +19,6 @@ describe('modules/datasource/rubygems/index', () => {
   describe('getReleases', () => {
     beforeEach(() => {
       memCache.clear();
-      jest.resetAllMocks();
     });
 
     it('returns null for missing pkg', async () => {
diff --git a/lib/modules/datasource/rubygems/metadata-cache.spec.ts b/lib/modules/datasource/rubygems/metadata-cache.spec.ts
index ab7960f20306ea9cb884649b3d0ad8673984939c..7b376ac6eb60ca4e960b3189f6e07085b9729d2c 100644
--- a/lib/modules/datasource/rubygems/metadata-cache.spec.ts
+++ b/lib/modules/datasource/rubygems/metadata-cache.spec.ts
@@ -10,17 +10,17 @@ const packageCache = mocked(_packageCache);
 describe('modules/datasource/rubygems/metadata-cache', () => {
   const cache: Map<string, unknown> = new Map();
 
-  packageCache.get.mockImplementation(
-    (ns, key) => Promise.resolve(cache.get(`${ns}::${key}`)) as never
-  );
-
-  packageCache.set.mockImplementation((ns, key, value) => {
-    cache.set(`${ns}::${key}`, value);
-    return Promise.resolve() as never;
-  });
-
   beforeEach(() => {
     cache.clear();
+
+    packageCache.get.mockImplementation(
+      (ns, key) => Promise.resolve(cache.get(`${ns}::${key}`)) as never
+    );
+
+    packageCache.set.mockImplementation((ns, key, value) => {
+      cache.set(`${ns}::${key}`, value);
+      return Promise.resolve() as never;
+    });
   });
 
   it('fetches data', async () => {
diff --git a/lib/modules/manager/bazel-module/extract.spec.ts b/lib/modules/manager/bazel-module/extract.spec.ts
index 133b0f1e8ca8dc795fea3ac03b944604201a7fe9..96197b0f4be9e57a66bc787f2df62d191ce90e87 100644
--- a/lib/modules/manager/bazel-module/extract.spec.ts
+++ b/lib/modules/manager/bazel-module/extract.spec.ts
@@ -16,10 +16,7 @@ describe('modules/manager/bazel-module/extract', () => {
   describe('extractPackageFile()', () => {
     beforeEach(() => {
       GlobalConfig.set(adminConfig);
-    });
-
-    afterEach(() => {
-      GlobalConfig.reset();
+      jest.restoreAllMocks();
     });
 
     it('returns null if fails to parse', async () => {
@@ -31,7 +28,7 @@ describe('modules/manager/bazel-module/extract', () => {
     });
 
     it('returns null if something throws an error', async () => {
-      jest.spyOn(parser, 'parse').mockImplementationOnce((input) => {
+      jest.spyOn(parser, 'parse').mockImplementationOnce(() => {
         throw new Error('Test error');
       });
       const result = await extractPackageFile('content', 'MODULE.bazel');
@@ -54,9 +51,9 @@ describe('modules/manager/bazel-module/extract', () => {
     it('returns bazel_dep and git_override dependencies', async () => {
       const input = codeBlock`
         bazel_dep(name = "rules_foo", version = "1.2.3")
-        
+
         bazel_dep(name = "rules_bar", version = "1.0.0", dev_dependency = True)
-        
+
         git_override(
             module_name = "rules_foo",
             commit = "850cb49c8649e463b80ef7984e7c744279746170",
diff --git a/lib/modules/manager/bundler/artifacts.spec.ts b/lib/modules/manager/bundler/artifacts.spec.ts
index f90b772d99bb5364486896cbe1075bfcc1ba962b..d4bbf4d8b8e8661ad265250a400456aece039828 100644
--- a/lib/modules/manager/bundler/artifacts.spec.ts
+++ b/lib/modules/manager/bundler/artifacts.spec.ts
@@ -1,3 +1,4 @@
+import { mockDeep } from 'jest-mock-extended';
 import { join } from 'upath';
 import {
   envMock,
@@ -23,10 +24,10 @@ const datasource = mocked(_datasource);
 const bundlerHostRules = mocked(_bundlerHostRules);
 
 jest.mock('../../../util/exec/env');
-jest.mock('../../datasource');
+jest.mock('../../datasource', () => mockDeep());
 jest.mock('../../../util/fs');
 jest.mock('../../../util/git');
-jest.mock('../../../util/host-rules');
+jest.mock('../../../util/host-rules', () => mockDeep());
 jest.mock('./host-rules');
 
 process.env.CONTAINERBASE = 'true';
@@ -52,7 +53,6 @@ const updatedGemfileLock = {
 describe('modules/manager/bundler/artifacts', () => {
   describe('updateArtifacts', () => {
     beforeEach(() => {
-      jest.resetAllMocks();
       jest.resetModules();
 
       delete process.env.GEM_HOME;
diff --git a/lib/modules/manager/cargo/artifacts.spec.ts b/lib/modules/manager/cargo/artifacts.spec.ts
index 5850ba51b38dc8504364a62a02eb4b3a6bdb6c46..f035d46a6e3821412080631e9cac729bf6bc39fd 100644
--- a/lib/modules/manager/cargo/artifacts.spec.ts
+++ b/lib/modules/manager/cargo/artifacts.spec.ts
@@ -26,9 +26,6 @@ const adminConfig: RepoGlobalConfig = {
 
 describe('modules/manager/cargo/artifacts', () => {
   beforeEach(() => {
-    jest.resetAllMocks();
-    jest.resetModules();
-
     env.getChildProcessEnv.mockReturnValue(envMock.basic);
     GlobalConfig.set(adminConfig);
     docker.resetPrefetchedImages();
diff --git a/lib/modules/manager/cocoapods/artifacts.spec.ts b/lib/modules/manager/cocoapods/artifacts.spec.ts
index 80d6e085ca0647465d27d417a6beb1160cacac9d..fcffceaccf586d7e813d96d4ece9b7aa384788ce 100644
--- a/lib/modules/manager/cocoapods/artifacts.spec.ts
+++ b/lib/modules/manager/cocoapods/artifacts.spec.ts
@@ -1,3 +1,4 @@
+import { mockDeep } from 'jest-mock-extended';
 import { join } from 'upath';
 import { envMock, mockExecAll } from '../../../../test/exec-util';
 import { env, fs, git, mocked, partial } from '../../../../test/util';
@@ -12,8 +13,7 @@ import { updateArtifacts } from '.';
 jest.mock('../../../util/exec/env');
 jest.mock('../../../util/git');
 jest.mock('../../../util/fs');
-jest.mock('../../platform');
-jest.mock('../../datasource');
+jest.mock('../../datasource', () => mockDeep());
 
 const datasource = mocked(_datasource);
 
@@ -31,7 +31,6 @@ const adminConfig: RepoGlobalConfig = {
 
 describe('modules/manager/cocoapods/artifacts', () => {
   beforeEach(() => {
-    jest.resetAllMocks();
     env.getChildProcessEnv.mockReturnValue(envMock.basic);
     jest.spyOn(docker, 'removeDockerContainer').mockResolvedValue();
     // can't be mocked
diff --git a/lib/modules/manager/composer/artifacts.spec.ts b/lib/modules/manager/composer/artifacts.spec.ts
index 7ad1a8bc212fc6aca67e9dac48a35e12eb57119f..29fa33a66f631a0c7edbc7be77b9d79e0aec9240 100644
--- a/lib/modules/manager/composer/artifacts.spec.ts
+++ b/lib/modules/manager/composer/artifacts.spec.ts
@@ -1,3 +1,4 @@
+import { mockDeep } from 'jest-mock-extended';
 import { join } from 'upath';
 import { envMock, mockExecAll } from '../../../../test/exec-util';
 import { env, fs, git, mocked, partial } from '../../../../test/util';
@@ -13,7 +14,7 @@ import type { UpdateArtifactsConfig } from '../types';
 import * as composer from '.';
 
 jest.mock('../../../util/exec/env');
-jest.mock('../../datasource');
+jest.mock('../../datasource', () => mockDeep());
 jest.mock('../../../util/fs');
 jest.mock('../../../util/git');
 
@@ -44,8 +45,6 @@ const repoStatus = partial<StatusResult>({
 
 describe('modules/manager/composer/artifacts', () => {
   beforeEach(() => {
-    jest.resetAllMocks();
-    jest.resetModules();
     env.getChildProcessEnv.mockReturnValue(envMock.basic);
     docker.resetPrefetchedImages();
     hostRules.clear();
diff --git a/lib/modules/manager/composer/utils.spec.ts b/lib/modules/manager/composer/utils.spec.ts
index 7078bc6356690c0d37ea4af05ce577c3a8cdf69d..46abbf0fcc75fbca068f3937546abeb480e8a57b 100644
--- a/lib/modules/manager/composer/utils.spec.ts
+++ b/lib/modules/manager/composer/utils.spec.ts
@@ -1,3 +1,4 @@
+import { mockDeep } from 'jest-mock-extended';
 import { GlobalConfig } from '../../../config/global';
 import * as hostRules from '../../../util/host-rules';
 import { Lockfile, PackageFile } from './schema';
@@ -7,7 +8,7 @@ import {
   requireComposerDependencyInstallation,
 } from './utils';
 
-jest.mock('../../datasource');
+jest.mock('../../datasource', () => mockDeep());
 
 describe('modules/manager/composer/utils', () => {
   beforeEach(() => {
diff --git a/lib/modules/manager/git-submodules/extract.spec.ts b/lib/modules/manager/git-submodules/extract.spec.ts
index 6e756d0c0a20efb1d6fad685396b90c85bb6cc70..42f4a289a27683aab30b7b833a4de84d231a4fc3 100644
--- a/lib/modules/manager/git-submodules/extract.spec.ts
+++ b/lib/modules/manager/git-submodules/extract.spec.ts
@@ -7,8 +7,7 @@ import { extractPackageFile } from '.';
 
 jest.mock('simple-git');
 const simpleGitFactoryMock = simpleGit as jest.Mock<Partial<SimpleGit>>;
-// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
-const Git = jest.requireActual('simple-git') as SimpleGitFactory;
+const Git = jest.requireActual<SimpleGitFactory>('simple-git');
 
 const gitMock = mock<SimpleGit>();
 
diff --git a/lib/modules/manager/gomod/artifacts.spec.ts b/lib/modules/manager/gomod/artifacts.spec.ts
index 9dfbf2f1f08179c108477a9e9992332091571b54..9e09f9c6abfb18b1e64f6c8ee9f0e9514f4c6c15 100644
--- a/lib/modules/manager/gomod/artifacts.spec.ts
+++ b/lib/modules/manager/gomod/artifacts.spec.ts
@@ -1,4 +1,5 @@
 import { codeBlock } from 'common-tags';
+import { mockDeep } from 'jest-mock-extended';
 import { join } from 'upath';
 import { envMock, mockExecAll } from '../../../../test/exec-util';
 import { env, fs, git, mocked, partial } from '../../../../test/util';
@@ -11,22 +12,22 @@ import * as _datasource from '../../datasource';
 import type { UpdateArtifactsConfig } from '../types';
 import * as gomod from '.';
 
+type FS = typeof import('../../../util/fs');
+
 jest.mock('../../../util/exec/env');
 jest.mock('../../../util/git');
-jest.mock('../../../util/host-rules');
+jest.mock('../../../util/host-rules', () => mockDeep());
 jest.mock('../../../util/http');
 jest.mock('../../../util/fs', () => {
   // restore
   return {
     __esModules: true,
-    // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
-    ...(jest.createMockFromModule('../../../util/fs') as any),
-    // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
-    isValidLocalPath: (jest.requireActual('../../../util/fs') as any)
-      .isValidLocalPath,
+    ...jest.createMockFromModule<FS>('../../../util/fs'),
+    isValidLocalPath:
+      jest.requireActual<FS>('../../../util/fs').isValidLocalPath,
   };
 });
-jest.mock('../../datasource');
+jest.mock('../../datasource', () => mockDeep());
 
 process.env.CONTAINERBASE = 'true';
 
@@ -78,9 +79,6 @@ const goEnv = {
 
 describe('modules/manager/gomod/artifacts', () => {
   beforeEach(() => {
-    jest.resetAllMocks();
-    jest.resetModules();
-
     delete process.env.GOPATH;
     env.getChildProcessEnv.mockReturnValue({ ...envMock.basic, ...goEnv });
     GlobalConfig.set(adminConfig);
diff --git a/lib/modules/manager/gradle-wrapper/artifacts.spec.ts b/lib/modules/manager/gradle-wrapper/artifacts.spec.ts
index 4f4ec1028a280b1dc2cadf6168fb595888847e04..039dcb7fb8a353e92dd3c525792ba8956ff4279f 100644
--- a/lib/modules/manager/gradle-wrapper/artifacts.spec.ts
+++ b/lib/modules/manager/gradle-wrapper/artifacts.spec.ts
@@ -1,5 +1,6 @@
 import type { Stats } from 'node:fs';
 import os from 'node:os';
+import { mockDeep } from 'jest-mock-extended';
 import { join } from 'upath';
 import { envMock, mockExecAll } from '../../../../test/exec-util';
 import { Fixtures } from '../../../../test/fixtures';
@@ -25,7 +26,7 @@ import { updateArtifacts } from '.';
 jest.mock('../../../util/fs');
 jest.mock('../../../util/git');
 jest.mock('../../../util/exec/env');
-jest.mock('../../datasource');
+jest.mock('../../datasource', () => mockDeep());
 jest.mock('../gradle');
 
 process.env.CONTAINERBASE = 'true';
diff --git a/lib/modules/manager/gradle/artifacts.spec.ts b/lib/modules/manager/gradle/artifacts.spec.ts
index 6cf4420d517fc5147146c1ad2626d58d66e87bef..b8ed96d8255210c5044043c6fa29a3dff7240586 100644
--- a/lib/modules/manager/gradle/artifacts.spec.ts
+++ b/lib/modules/manager/gradle/artifacts.spec.ts
@@ -1,4 +1,5 @@
 import os from 'node:os';
+import { mockDeep } from 'jest-mock-extended';
 import { join } from 'upath';
 import {
   envMock,
@@ -26,7 +27,7 @@ import { updateArtifacts } from '.';
 jest.mock('../../../util/fs');
 jest.mock('../../../util/git');
 jest.mock('../../../util/exec/env');
-jest.mock('../../datasource');
+jest.mock('../../datasource', () => mockDeep());
 
 process.env.CONTAINERBASE = 'true';
 
diff --git a/lib/modules/manager/gradle/extract.spec.ts b/lib/modules/manager/gradle/extract.spec.ts
index d007dd7ff3ff51a4a9a69507085a8c5d5b270f39..b6ad592650620ceef439e2d92fdef23962599a59 100644
--- a/lib/modules/manager/gradle/extract.spec.ts
+++ b/lib/modules/manager/gradle/extract.spec.ts
@@ -28,8 +28,8 @@ function mockFs(files: Record<string, string>): void {
 }
 
 describe('modules/manager/gradle/extract', () => {
-  afterAll(() => {
-    jest.resetAllMocks();
+  beforeEach(() => {
+    jest.restoreAllMocks();
   });
 
   it('returns null', async () => {
diff --git a/lib/modules/manager/gradle/extract/consistent-versions-plugin.spec.ts b/lib/modules/manager/gradle/extract/consistent-versions-plugin.spec.ts
index 4598295f8ab6167ac3715ca20dc55b7857454330..c5e89a4dd9f50a303a772d42231c7d0a3c34fed7 100644
--- a/lib/modules/manager/gradle/extract/consistent-versions-plugin.spec.ts
+++ b/lib/modules/manager/gradle/extract/consistent-versions-plugin.spec.ts
@@ -6,10 +6,6 @@ import {
 } from './consistent-versions-plugin';
 
 describe('modules/manager/gradle/extract/consistent-versions-plugin', () => {
-  afterAll(() => {
-    jest.resetAllMocks();
-  });
-
   it('gradle-consistent-versions plugin works for sub folders', () => {
     const fsMock = {
       'mysub/build.gradle.kts': `(this file contains) 'com.palantir.consistent-versions'`,
diff --git a/lib/modules/manager/helm-requirements/extract.spec.ts b/lib/modules/manager/helm-requirements/extract.spec.ts
index ebb9748a1916e4fbf87d6f4157a995ce0e579db3..e203872bddae685140a6d3b221066f68693bf398 100644
--- a/lib/modules/manager/helm-requirements/extract.spec.ts
+++ b/lib/modules/manager/helm-requirements/extract.spec.ts
@@ -5,11 +5,6 @@ jest.mock('../../../util/fs');
 
 describe('modules/manager/helm-requirements/extract', () => {
   describe('extractPackageFile()', () => {
-    beforeEach(() => {
-      jest.resetAllMocks();
-      fs.readLocalFile = jest.fn();
-    });
-
     it('ensure that currentValue is string', () => {
       fs.readLocalFile.mockResolvedValueOnce(`
       apiVersion: v1
diff --git a/lib/modules/manager/helm-values/extract.spec.ts b/lib/modules/manager/helm-values/extract.spec.ts
index 9798984a8816618c30106893a3d71e3ea0e08a4f..3666b8441349bbeb448577a061f5ac87b48848c2 100644
--- a/lib/modules/manager/helm-values/extract.spec.ts
+++ b/lib/modules/manager/helm-values/extract.spec.ts
@@ -11,10 +11,6 @@ const helmMultiAndNestedImageValues = Fixtures.get(
 
 describe('modules/manager/helm-values/extract', () => {
   describe('extractPackageFile()', () => {
-    beforeEach(() => {
-      jest.resetAllMocks();
-    });
-
     it('returns null for invalid yaml file content', () => {
       const result = extractPackageFile('nothing here: [');
       expect(result).toBeNull();
diff --git a/lib/modules/manager/helmfile/artifacts.spec.ts b/lib/modules/manager/helmfile/artifacts.spec.ts
index 10eaa9fd7d9e3dd72420c62c370f16501fca7354..a64c46e68fc42f232921279be370a4bb637ed377 100644
--- a/lib/modules/manager/helmfile/artifacts.spec.ts
+++ b/lib/modules/manager/helmfile/artifacts.spec.ts
@@ -1,4 +1,5 @@
 import { codeBlock } from 'common-tags';
+import { mockDeep } from 'jest-mock-extended';
 import { join } from 'upath';
 import { envMock, mockExecAll } from '../../../../test/exec-util';
 import { env, fs, git, mocked } from '../../../../test/util';
@@ -10,7 +11,7 @@ import * as _datasource from '../../datasource';
 import type { UpdateArtifactsConfig } from '../types';
 import * as helmfile from '.';
 
-jest.mock('../../datasource');
+jest.mock('../../datasource', () => mockDeep());
 jest.mock('../../../util/exec/env');
 jest.mock('../../../util/http');
 jest.mock('../../../util/fs');
diff --git a/lib/modules/manager/helmfile/extract.spec.ts b/lib/modules/manager/helmfile/extract.spec.ts
index 10f9281a33e059cae321115f8bb99be56d8ae4c9..891ad097aa646ca3e775257639cfda5558fe60e2 100644
--- a/lib/modules/manager/helmfile/extract.spec.ts
+++ b/lib/modules/manager/helmfile/extract.spec.ts
@@ -12,7 +12,6 @@ describe('modules/manager/helmfile/extract', () => {
   describe('extractPackageFile()', () => {
     beforeEach(() => {
       GlobalConfig.set({ localDir });
-      jest.resetAllMocks();
     });
 
     it('returns null if no releases', async () => {
diff --git a/lib/modules/manager/helmv3/artifacts.spec.ts b/lib/modules/manager/helmv3/artifacts.spec.ts
index ff8e5b3ee941538f86ad981fd11cc6af753a5a21..a0166b1a2ba6127b3066e2347325570ce8996a52 100644
--- a/lib/modules/manager/helmv3/artifacts.spec.ts
+++ b/lib/modules/manager/helmv3/artifacts.spec.ts
@@ -1,3 +1,4 @@
+import { mockDeep } from 'jest-mock-extended';
 import { join } from 'upath';
 import { envMock, mockExecAll } from '../../../../test/exec-util';
 import { Fixtures } from '../../../../test/fixtures';
@@ -11,7 +12,7 @@ import * as _datasource from '../../datasource';
 import type { UpdateArtifactsConfig } from '../types';
 import * as helmv3 from '.';
 
-jest.mock('../../datasource');
+jest.mock('../../datasource', () => mockDeep());
 jest.mock('../../../util/exec/env');
 jest.mock('../../../util/http');
 jest.mock('../../../util/fs');
@@ -36,9 +37,6 @@ const chartFileAlias = Fixtures.get('ChartAlias.yaml');
 
 describe('modules/manager/helmv3/artifacts', () => {
   beforeEach(() => {
-    jest.resetAllMocks();
-    jest.resetModules();
-
     env.getChildProcessEnv.mockReturnValue(envMock.basic);
     GlobalConfig.set(adminConfig);
     docker.resetPrefetchedImages();
diff --git a/lib/modules/manager/helmv3/extract.spec.ts b/lib/modules/manager/helmv3/extract.spec.ts
index eb0d0041778c896355b17b739592c33711c4cfdd..916cd2ba54a6f92b0cece8977c6bee33bd6bb1e1 100644
--- a/lib/modules/manager/helmv3/extract.spec.ts
+++ b/lib/modules/manager/helmv3/extract.spec.ts
@@ -12,11 +12,6 @@ const config = partial<ExtractConfig>({
 
 describe('modules/manager/helmv3/extract', () => {
   describe('extractPackageFile()', () => {
-    beforeEach(() => {
-      jest.resetAllMocks();
-      fs.readLocalFile = jest.fn();
-    });
-
     it('skips invalid registry urls', async () => {
       const content = `
       apiVersion: v2
diff --git a/lib/modules/manager/homebrew/update.spec.ts b/lib/modules/manager/homebrew/update.spec.ts
index 013f4fa4c42a3b86f9627f993cf4a4fae970d3d8..c57a28858abbea5d441efa203a7aff41bca2ba18 100644
--- a/lib/modules/manager/homebrew/update.spec.ts
+++ b/lib/modules/manager/homebrew/update.spec.ts
@@ -9,11 +9,6 @@ const ibazel = Fixtures.get('ibazel.rb');
 const baseUrl = 'https://github.com';
 
 describe('modules/manager/homebrew/update', () => {
-  beforeEach(() => {
-    jest.resetAllMocks();
-    jest.resetModules();
-  });
-
   it('updates "releases" github dependency', async () => {
     const upgrade = {
       currentValue: 'v0.16.1',
diff --git a/lib/modules/manager/maven-wrapper/artifacts.spec.ts b/lib/modules/manager/maven-wrapper/artifacts.spec.ts
index 023249152b02503b8dac6bc5c865afd4eacb26a8..06fa35f79254bb5e885ed95ccdcb19bc36c84518 100644
--- a/lib/modules/manager/maven-wrapper/artifacts.spec.ts
+++ b/lib/modules/manager/maven-wrapper/artifacts.spec.ts
@@ -1,5 +1,6 @@
 import type { Stats } from 'node:fs';
 import os from 'node:os';
+import { mockDeep } from 'jest-mock-extended';
 import type { StatusResult } from 'simple-git';
 import { join } from 'upath';
 import { envMock, mockExecAll } from '../../../../test/exec-util';
@@ -12,7 +13,7 @@ import { updateArtifacts } from '.';
 jest.mock('../../../util/fs');
 jest.mock('../../../util/git');
 jest.mock('../../../util/exec/env');
-jest.mock('../../datasource');
+jest.mock('../../datasource', () => mockDeep());
 
 process.env.CONTAINERBASE = 'true';
 
diff --git a/lib/modules/manager/mix/artifacts.spec.ts b/lib/modules/manager/mix/artifacts.spec.ts
index 0f1b12dd4f45c37f048be8d3ed99ceae36ee39ec..4115d207382743c0c58734324eb52706f211f10b 100644
--- a/lib/modules/manager/mix/artifacts.spec.ts
+++ b/lib/modules/manager/mix/artifacts.spec.ts
@@ -1,3 +1,4 @@
+import { mockDeep } from 'jest-mock-extended';
 import { join } from 'upath';
 import { envMock, mockExecAll } from '../../../../test/exec-util';
 import { env, fs, hostRules, mockedFunction } from '../../../../test/util';
@@ -10,8 +11,8 @@ import { updateArtifacts } from '.';
 
 jest.mock('../../../util/exec/env');
 jest.mock('../../../util/fs');
-jest.mock('../../../util/host-rules');
-jest.mock('../../datasource');
+jest.mock('../../../util/host-rules', () => mockDeep());
+jest.mock('../../datasource', () => mockDeep());
 
 const getPkgReleases = mockedFunction(_getPkgReleases);
 
@@ -29,8 +30,6 @@ const config: UpdateArtifactsConfig = {};
 
 describe('modules/manager/mix/artifacts', () => {
   beforeEach(() => {
-    jest.resetAllMocks();
-    jest.resetModules();
     hostRules.getAll.mockReturnValue([]);
 
     env.getChildProcessEnv.mockReturnValue(envMock.basic);
diff --git a/lib/modules/manager/nix/artifacts.spec.ts b/lib/modules/manager/nix/artifacts.spec.ts
index 779513f29c00c8e74e02d9cc7568bb42a3c34b2d..9b58b41cc0baed824308b0bf36b7783ec65f5d99 100644
--- a/lib/modules/manager/nix/artifacts.spec.ts
+++ b/lib/modules/manager/nix/artifacts.spec.ts
@@ -1,3 +1,4 @@
+import { mockDeep } from 'jest-mock-extended';
 import type { StatusResult } from 'simple-git';
 import { join } from 'upath';
 import {
@@ -16,7 +17,7 @@ import { updateArtifacts } from '.';
 jest.mock('../../../util/exec/env');
 jest.mock('../../../util/fs');
 jest.mock('../../../util/git');
-jest.mock('../../../util/host-rules');
+jest.mock('../../../util/host-rules', () => mockDeep());
 
 const adminConfig: RepoGlobalConfig = {
   // `join` fixes Windows CI
@@ -52,7 +53,6 @@ describe('modules/manager/nix/artifacts', () => {
   const hostRules = mocked(_hostRules);
 
   beforeEach(() => {
-    jest.resetAllMocks();
     env.getChildProcessEnv.mockReturnValue({
       ...envMock.basic,
       LANG: 'en_US.UTF-8',
diff --git a/lib/modules/manager/npm/extract/index.spec.ts b/lib/modules/manager/npm/extract/index.spec.ts
index f9c34b2c4a7a34a5a7a0631ae93463f5da22603b..bf32d35ceefef36e5b9736e7f5e898d166e061e2 100644
--- a/lib/modules/manager/npm/extract/index.spec.ts
+++ b/lib/modules/manager/npm/extract/index.spec.ts
@@ -5,9 +5,6 @@ import type { ExtractConfig } from '../../types';
 import * as npmExtract from '.';
 
 jest.mock('../../../../util/fs');
-const realFs = jest.requireActual<typeof import('../../../../util/fs')>(
-  '../../../../util/fs'
-);
 
 const defaultExtractConfig = {
   skipInstalls: null,
@@ -27,7 +24,7 @@ const invalidNameContent = Fixtures.get('invalid-name.json', '..');
 describe('modules/manager/npm/extract/index', () => {
   describe('.extractPackageFile()', () => {
     beforeEach(() => {
-      jest.resetAllMocks();
+      const realFs = jest.requireActual<typeof fs>('../../../../util/fs');
       fs.readLocalFile.mockResolvedValue(null);
       fs.localPathExists.mockResolvedValue(false);
       fs.getSiblingFileName.mockImplementation(realFs.getSiblingFileName);
diff --git a/lib/modules/manager/npm/extract/locked-versions.spec.ts b/lib/modules/manager/npm/extract/locked-versions.spec.ts
index c63a8494d8b4283a558d54dc03cf1753b081ef86..8d4e8ce57ce8b0d09804caf09299d4440e268b0a 100644
--- a/lib/modules/manager/npm/extract/locked-versions.spec.ts
+++ b/lib/modules/manager/npm/extract/locked-versions.spec.ts
@@ -12,7 +12,7 @@ const yarn = mocked(_yarn);
 
 jest.mock('./npm');
 jest.mock('./yarn', () => ({
-  ...jest.requireActual<any>('./yarn'),
+  ...jest.requireActual<typeof import('./yarn')>('./yarn'),
   getYarnLock: jest.fn(),
 }));
 jest.mock('./pnpm');
diff --git a/lib/modules/manager/npm/extract/pnpm.spec.ts b/lib/modules/manager/npm/extract/pnpm.spec.ts
index c44a66257cf3ff68bc1ecd016d254d5fbb68a14e..26227db1b0b3bd81961ae502bd71d0b0fe20f429 100644
--- a/lib/modules/manager/npm/extract/pnpm.spec.ts
+++ b/lib/modules/manager/npm/extract/pnpm.spec.ts
@@ -1,8 +1,10 @@
 import yaml from 'js-yaml';
 import { Fixtures } from '../../../../../test/fixtures';
-import { getFixturePath, logger } from '../../../../../test/util';
+import { getFixturePath, logger, partial } from '../../../../../test/util';
 import { GlobalConfig } from '../../../../config/global';
 import * as fs from '../../../../util/fs';
+import type { PackageFile } from '../../types';
+import type { NpmManagerData } from '../types';
 import {
   detectPnpmWorkspaces,
   extractPnpmFilters,
@@ -15,6 +17,10 @@ describe('modules/manager/npm/extract/pnpm', () => {
     GlobalConfig.set({ localDir: getFixturePath('pnpm-monorepo/', '..') });
   });
 
+  beforeEach(() => {
+    jest.restoreAllMocks();
+  });
+
   describe('.extractPnpmFilters()', () => {
     it('detects errors in pnpm-workspace.yml file structure', async () => {
       jest
@@ -66,6 +72,9 @@ describe('modules/manager/npm/extract/pnpm', () => {
     });
 
     it('detects missing pnpm-lock.yaml when pnpm-workspace.yaml was already found', async () => {
+      jest
+        .spyOn(fs, 'findLocalSiblingOrParent')
+        .mockResolvedValueOnce('pnpm-workspace.yaml');
       jest.spyOn(fs, 'localPathExists').mockResolvedValueOnce(false);
 
       const packageFile = 'package.json';
@@ -83,7 +92,7 @@ describe('modules/manager/npm/extract/pnpm', () => {
 
   describe('.detectPnpmWorkspaces()', () => {
     it('uses pnpm workspaces', async () => {
-      const packageFiles = [
+      const packageFiles = partial<PackageFile<NpmManagerData>>([
         {
           packageFile: 'package.json',
           managerData: { pnpmShrinkwrap: 'pnpm-lock.yaml' },
@@ -91,80 +100,80 @@ describe('modules/manager/npm/extract/pnpm', () => {
         {
           packageFile: 'nested-packages/group/a/package.json',
           managerData: {
-            pnpmShrinkwrap: undefined as undefined | string,
+            pnpmShrinkwrap: undefined,
             packageJsonName: '@demo/nested-group-a',
           },
         },
         {
           packageFile: 'nested-packages/group/b/package.json',
           managerData: {
-            pnpmShrinkwrap: undefined as undefined | string,
+            pnpmShrinkwrap: undefined,
             packageJsonName: '@demo/nested-group-b',
           },
         },
         {
           packageFile: 'non-nested-packages/a/package.json',
           managerData: {
-            pnpmShrinkwrap: undefined as undefined | string,
+            pnpmShrinkwrap: undefined,
             packageJsonName: '@demo/non-nested-a',
           },
         },
         {
           packageFile: 'non-nested-packages/b/package.json',
           managerData: {
-            pnpmShrinkwrap: undefined as undefined | string,
+            pnpmShrinkwrap: undefined,
             packageJsonName: '@demo/non-nested-b',
           },
         },
         {
           packageFile: 'solo-package/package.json',
           managerData: {
-            pnpmShrinkwrap: undefined as undefined | string,
+            pnpmShrinkwrap: undefined,
             packageJsonName: '@demo/solo',
           },
         },
         {
           packageFile: 'solo-package-leading-dot-slash/package.json',
           managerData: {
-            pnpmShrinkwrap: undefined as undefined | string,
+            pnpmShrinkwrap: undefined,
             packageJsonName: '@demo/solo-leading-dot-slash',
           },
         },
         {
           packageFile: 'solo-package-leading-double-dot-slash/package.json',
           managerData: {
-            pnpmShrinkwrap: undefined as undefined | string,
+            pnpmShrinkwrap: undefined,
             packageJsonName: '@demo/solo-leading-double-dot-slash',
           },
         },
         {
           packageFile: 'solo-package-trailing-slash/package.json',
           managerData: {
-            pnpmShrinkwrap: undefined as undefined | string,
+            pnpmShrinkwrap: undefined,
             packageJsonName: '@demo/solo-trailing-slash',
           },
         },
         {
           packageFile: 'test/test-package/package.json',
           managerData: {
-            pnpmShrinkwrap: undefined as undefined | string,
+            pnpmShrinkwrap: undefined,
             packageJsonName: '@demo/test-package',
           },
         },
         {
           packageFile: 'tests/test-package2/package.json',
           managerData: {
-            pnpmShrinkwrap: undefined as undefined | string,
+            pnpmShrinkwrap: undefined,
             packageJsonName: '@demo/test-package2',
           },
         },
-      ];
+      ]);
 
       await detectPnpmWorkspaces(packageFiles);
       expect(packageFiles).toMatchSnapshot();
       expect(
         packageFiles.every(
-          (packageFile) => packageFile.managerData.pnpmShrinkwrap
+          (packageFile) => packageFile.managerData?.pnpmShrinkwrap !== undefined
         )
       ).toBeTrue();
     });
@@ -195,12 +204,12 @@ describe('modules/manager/npm/extract/pnpm', () => {
         {
           packageFile: 'nested-packages/group/a/package.json',
           packageJsonName: '@demo/nested-group-a',
-          managerData: { pnpmShrinkwrap: undefined as undefined | string },
+          managerData: { pnpmShrinkwrap: undefined },
         },
         {
           packageFile: 'not-matching/b/package.json',
           packageJsonName: '@not-matching/b',
-          managerData: { pnpmShrinkwrap: undefined as undefined | string },
+          managerData: { pnpmShrinkwrap: undefined },
         },
       ];
 
@@ -231,17 +240,15 @@ describe('modules/manager/npm/extract/pnpm', () => {
   });
 
   describe('.getPnpmLock()', () => {
-    const readLocalFile = jest.spyOn(fs, 'readLocalFile');
-
     it('returns empty if failed to parse', async () => {
-      readLocalFile.mockResolvedValueOnce(undefined as never);
+      jest.spyOn(fs, 'readLocalFile').mockResolvedValueOnce(undefined as never);
       const res = await getPnpmLock('package.json');
       expect(res.lockedVersionsWithPath).toBeUndefined();
     });
 
     it('extracts version from monorepo', async () => {
       const plocktest1Lock = Fixtures.get('pnpm-monorepo/pnpm-lock.yaml', '..');
-      readLocalFile.mockResolvedValueOnce(plocktest1Lock);
+      jest.spyOn(fs, 'readLocalFile').mockResolvedValueOnce(plocktest1Lock);
       const res = await getPnpmLock('package.json');
       expect(Object.keys(res.lockedVersionsWithPath!)).toHaveLength(11);
     });
@@ -251,13 +258,13 @@ describe('modules/manager/npm/extract/pnpm', () => {
         'lockfile-parsing/pnpm-lock.yaml',
         '..'
       );
-      readLocalFile.mockResolvedValueOnce(plocktest1Lock);
+      jest.spyOn(fs, 'readLocalFile').mockResolvedValueOnce(plocktest1Lock);
       const res = await getPnpmLock('package.json');
       expect(Object.keys(res.lockedVersionsWithPath!)).toHaveLength(1);
     });
 
     it('returns empty if no deps', async () => {
-      readLocalFile.mockResolvedValueOnce('{}');
+      jest.spyOn(fs, 'readLocalFile').mockResolvedValueOnce('{}');
       const res = await getPnpmLock('package.json');
       expect(res.lockedVersionsWithPath).toBeUndefined();
     });
diff --git a/lib/modules/manager/npm/post-update/__snapshots__/yarn.spec.ts.snap b/lib/modules/manager/npm/post-update/__snapshots__/yarn.spec.ts.snap
index 98f903a0ce382923486ea9c3cdafed8f8c5f3030..dd9dccc6e91a43c0b4d73a5dede4be5b44b84583 100644
--- a/lib/modules/manager/npm/post-update/__snapshots__/yarn.spec.ts.snap
+++ b/lib/modules/manager/npm/post-update/__snapshots__/yarn.spec.ts.snap
@@ -9,13 +9,6 @@ exports[`modules/manager/npm/post-update/yarn allows and ignore scripts 1`] = `
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
         "YARN_ENABLE_GLOBAL_CACHE": "1",
         "YARN_ENABLE_IMMUTABLE_INSTALLS": "false",
         "YARN_HTTP_TIMEOUT": "100000",
@@ -36,13 +29,6 @@ exports[`modules/manager/npm/post-update/yarn catches errors 1`] = `
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
       },
       "maxBuffer": 10485760,
       "timeout": 900000,
@@ -60,13 +46,6 @@ exports[`modules/manager/npm/post-update/yarn does not use global cache if zero
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
         "YARN_ENABLE_IMMUTABLE_INSTALLS": "false",
         "YARN_ENABLE_SCRIPTS": "0",
         "YARN_HTTP_TIMEOUT": "100000",
@@ -87,13 +66,6 @@ exports[`modules/manager/npm/post-update/yarn generates lock files using yarn v1
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
         "YARN_CACHE_FOLDER": "/tmp/renovate/cache/yarn",
       },
       "maxBuffer": 10485760,
@@ -107,13 +79,6 @@ exports[`modules/manager/npm/post-update/yarn generates lock files using yarn v1
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
         "YARN_CACHE_FOLDER": "/tmp/renovate/cache/yarn",
       },
       "maxBuffer": 10485760,
@@ -127,13 +92,6 @@ exports[`modules/manager/npm/post-update/yarn generates lock files using yarn v1
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
         "YARN_CACHE_FOLDER": "/tmp/renovate/cache/yarn",
       },
       "maxBuffer": 10485760,
@@ -147,13 +105,6 @@ exports[`modules/manager/npm/post-update/yarn generates lock files using yarn v1
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
         "YARN_CACHE_FOLDER": "/tmp/renovate/cache/yarn",
       },
       "maxBuffer": 10485760,
@@ -167,13 +118,6 @@ exports[`modules/manager/npm/post-update/yarn generates lock files using yarn v1
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
         "YARN_CACHE_FOLDER": "/tmp/renovate/cache/yarn",
       },
       "maxBuffer": 10485760,
@@ -192,13 +136,6 @@ exports[`modules/manager/npm/post-update/yarn generates lock files using yarn v2
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
         "YARN_ENABLE_GLOBAL_CACHE": "1",
         "YARN_ENABLE_IMMUTABLE_INSTALLS": "false",
         "YARN_ENABLE_SCRIPTS": "0",
@@ -221,13 +158,6 @@ exports[`modules/manager/npm/post-update/yarn generates lock files using yarn v2
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
         "YARN_ENABLE_GLOBAL_CACHE": "1",
         "YARN_ENABLE_IMMUTABLE_INSTALLS": "false",
         "YARN_ENABLE_SCRIPTS": "0",
@@ -245,13 +175,6 @@ exports[`modules/manager/npm/post-update/yarn generates lock files using yarn v2
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
         "YARN_ENABLE_GLOBAL_CACHE": "1",
         "YARN_ENABLE_IMMUTABLE_INSTALLS": "false",
         "YARN_ENABLE_SCRIPTS": "0",
@@ -274,13 +197,6 @@ exports[`modules/manager/npm/post-update/yarn generates lock files using yarn v3
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
         "YARN_ENABLE_GLOBAL_CACHE": "1",
         "YARN_ENABLE_IMMUTABLE_INSTALLS": "false",
         "YARN_GLOBAL_FOLDER": "/tmp/renovate/cache/berry",
@@ -297,13 +213,6 @@ exports[`modules/manager/npm/post-update/yarn generates lock files using yarn v3
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
         "YARN_ENABLE_GLOBAL_CACHE": "1",
         "YARN_ENABLE_IMMUTABLE_INSTALLS": "false",
         "YARN_GLOBAL_FOLDER": "/tmp/renovate/cache/berry",
@@ -325,13 +234,6 @@ exports[`modules/manager/npm/post-update/yarn only skips build if skipInstalls i
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
         "YARN_ENABLE_GLOBAL_CACHE": "1",
         "YARN_ENABLE_IMMUTABLE_INSTALLS": "false",
         "YARN_HTTP_TIMEOUT": "100000",
@@ -347,13 +249,6 @@ exports[`modules/manager/npm/post-update/yarn only skips build if skipInstalls i
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
         "YARN_ENABLE_GLOBAL_CACHE": "1",
         "YARN_ENABLE_IMMUTABLE_INSTALLS": "false",
         "YARN_HTTP_TIMEOUT": "100000",
@@ -374,13 +269,6 @@ exports[`modules/manager/npm/post-update/yarn performs lock file maintenance in
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
       },
       "maxBuffer": 10485760,
       "timeout": 900000,
@@ -393,13 +281,6 @@ exports[`modules/manager/npm/post-update/yarn performs lock file maintenance in
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
       },
       "maxBuffer": 10485760,
       "timeout": 900000,
@@ -412,13 +293,6 @@ exports[`modules/manager/npm/post-update/yarn performs lock file maintenance in
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
       },
       "maxBuffer": 10485760,
       "timeout": 900000,
@@ -431,13 +305,6 @@ exports[`modules/manager/npm/post-update/yarn performs lock file maintenance in
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
       },
       "maxBuffer": 10485760,
       "timeout": 900000,
@@ -450,13 +317,6 @@ exports[`modules/manager/npm/post-update/yarn performs lock file maintenance in
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
       },
       "maxBuffer": 10485760,
       "timeout": 900000,
@@ -474,13 +334,6 @@ exports[`modules/manager/npm/post-update/yarn performs lock file maintenance in
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
         "YARN_ENABLE_GLOBAL_CACHE": "1",
         "YARN_ENABLE_IMMUTABLE_INSTALLS": "false",
         "YARN_ENABLE_SCRIPTS": "0",
@@ -502,13 +355,6 @@ exports[`modules/manager/npm/post-update/yarn performs lock file maintenance in
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
         "YARN_ENABLE_GLOBAL_CACHE": "1",
         "YARN_ENABLE_IMMUTABLE_INSTALLS": "false",
         "YARN_ENABLE_SCRIPTS": "0",
@@ -525,13 +371,6 @@ exports[`modules/manager/npm/post-update/yarn performs lock file maintenance in
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
         "YARN_ENABLE_GLOBAL_CACHE": "1",
         "YARN_ENABLE_IMMUTABLE_INSTALLS": "false",
         "YARN_ENABLE_SCRIPTS": "0",
@@ -553,13 +392,6 @@ exports[`modules/manager/npm/post-update/yarn performs lock file maintenance in
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
         "YARN_ENABLE_GLOBAL_CACHE": "1",
         "YARN_ENABLE_IMMUTABLE_INSTALLS": "false",
         "YARN_HTTP_TIMEOUT": "100000",
@@ -575,13 +407,6 @@ exports[`modules/manager/npm/post-update/yarn performs lock file maintenance in
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
         "YARN_ENABLE_GLOBAL_CACHE": "1",
         "YARN_ENABLE_IMMUTABLE_INSTALLS": "false",
         "YARN_HTTP_TIMEOUT": "100000",
@@ -602,13 +427,6 @@ exports[`modules/manager/npm/post-update/yarn performs lock file maintenance usi
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
       },
       "maxBuffer": 10485760,
       "timeout": 900000,
@@ -621,13 +439,6 @@ exports[`modules/manager/npm/post-update/yarn performs lock file maintenance usi
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
       },
       "maxBuffer": 10485760,
       "timeout": 900000,
@@ -640,13 +451,6 @@ exports[`modules/manager/npm/post-update/yarn performs lock file maintenance usi
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
       },
       "maxBuffer": 10485760,
       "timeout": 900000,
@@ -659,13 +463,6 @@ exports[`modules/manager/npm/post-update/yarn performs lock file maintenance usi
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
       },
       "maxBuffer": 10485760,
       "timeout": 900000,
@@ -678,13 +475,6 @@ exports[`modules/manager/npm/post-update/yarn performs lock file maintenance usi
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
       },
       "maxBuffer": 10485760,
       "timeout": 900000,
@@ -702,13 +492,6 @@ exports[`modules/manager/npm/post-update/yarn performs lock file maintenance usi
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
         "YARN_ENABLE_GLOBAL_CACHE": "1",
         "YARN_ENABLE_IMMUTABLE_INSTALLS": "false",
         "YARN_ENABLE_SCRIPTS": "0",
@@ -730,13 +513,6 @@ exports[`modules/manager/npm/post-update/yarn performs lock file maintenance usi
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
         "YARN_ENABLE_GLOBAL_CACHE": "1",
         "YARN_ENABLE_IMMUTABLE_INSTALLS": "false",
         "YARN_ENABLE_SCRIPTS": "0",
@@ -753,13 +529,6 @@ exports[`modules/manager/npm/post-update/yarn performs lock file maintenance usi
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
         "YARN_ENABLE_GLOBAL_CACHE": "1",
         "YARN_ENABLE_IMMUTABLE_INSTALLS": "false",
         "YARN_ENABLE_SCRIPTS": "0",
@@ -781,13 +550,6 @@ exports[`modules/manager/npm/post-update/yarn performs lock file updates and ful
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
       },
       "maxBuffer": 10485760,
       "timeout": 900000,
@@ -800,13 +562,6 @@ exports[`modules/manager/npm/post-update/yarn performs lock file updates and ful
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
       },
       "maxBuffer": 10485760,
       "timeout": 900000,
@@ -824,13 +579,6 @@ exports[`modules/manager/npm/post-update/yarn performs lock file updates using y
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
       },
       "maxBuffer": 10485760,
       "timeout": 900000,
@@ -843,13 +591,6 @@ exports[`modules/manager/npm/post-update/yarn performs lock file updates using y
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
       },
       "maxBuffer": 10485760,
       "timeout": 900000,
@@ -867,13 +608,6 @@ exports[`modules/manager/npm/post-update/yarn performs lock file updates using y
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
         "YARN_ENABLE_GLOBAL_CACHE": "1",
         "YARN_ENABLE_IMMUTABLE_INSTALLS": "false",
         "YARN_ENABLE_SCRIPTS": "0",
@@ -890,13 +624,6 @@ exports[`modules/manager/npm/post-update/yarn performs lock file updates using y
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
         "YARN_ENABLE_GLOBAL_CACHE": "1",
         "YARN_ENABLE_IMMUTABLE_INSTALLS": "false",
         "YARN_ENABLE_SCRIPTS": "0",
@@ -918,13 +645,6 @@ exports[`modules/manager/npm/post-update/yarn performs lock file updates using y
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
         "YARN_ENABLE_GLOBAL_CACHE": "1",
         "YARN_ENABLE_IMMUTABLE_INSTALLS": "false",
         "YARN_HTTP_TIMEOUT": "100000",
@@ -940,13 +660,6 @@ exports[`modules/manager/npm/post-update/yarn performs lock file updates using y
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
         "YARN_ENABLE_GLOBAL_CACHE": "1",
         "YARN_ENABLE_IMMUTABLE_INSTALLS": "false",
         "YARN_HTTP_TIMEOUT": "100000",
@@ -967,13 +680,6 @@ exports[`modules/manager/npm/post-update/yarn performs yarn binary update using
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
         "YARN_ENABLE_GLOBAL_CACHE": "1",
         "YARN_ENABLE_IMMUTABLE_INSTALLS": "false",
         "YARN_HTTP_TIMEOUT": "100000",
@@ -989,13 +695,6 @@ exports[`modules/manager/npm/post-update/yarn performs yarn binary update using
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
         "YARN_ENABLE_GLOBAL_CACHE": "1",
         "YARN_ENABLE_IMMUTABLE_INSTALLS": "false",
         "YARN_HTTP_TIMEOUT": "100000",
@@ -1016,13 +715,6 @@ exports[`modules/manager/npm/post-update/yarn performs yarn binary update using
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
         "YARN_ENABLE_GLOBAL_CACHE": "1",
         "YARN_ENABLE_IMMUTABLE_INSTALLS": "false",
         "YARN_HTTP_TIMEOUT": "100000",
@@ -1038,13 +730,6 @@ exports[`modules/manager/npm/post-update/yarn performs yarn binary update using
       "encoding": "utf-8",
       "env": {
         "CI": "true",
-        "HOME": "/home/user",
-        "HTTPS_PROXY": "https://example.com",
-        "HTTP_PROXY": "http://example.com",
-        "LANG": "en_US.UTF-8",
-        "LC_ALL": "en_US",
-        "NO_PROXY": "localhost",
-        "PATH": "/tmp/path",
         "YARN_ENABLE_GLOBAL_CACHE": "1",
         "YARN_ENABLE_IMMUTABLE_INSTALLS": "false",
         "YARN_HTTP_TIMEOUT": "100000",
diff --git a/lib/modules/manager/npm/post-update/index.spec.ts b/lib/modules/manager/npm/post-update/index.spec.ts
index 3f28dbbfe80db3dda5adbc197e165936068ee571..e6fd13d8496eab49f805f94e014d44d0169b4499 100644
--- a/lib/modules/manager/npm/post-update/index.spec.ts
+++ b/lib/modules/manager/npm/post-update/index.spec.ts
@@ -62,7 +62,6 @@ describe('modules/manager/npm/post-update/index', () => {
   };
 
   beforeEach(() => {
-    jest.resetAllMocks();
     GlobalConfig.set({ localDir: '' });
     baseConfig = partial<PostUpdateConfig>({
       upgrades: [],
diff --git a/lib/modules/manager/npm/post-update/lerna.spec.ts b/lib/modules/manager/npm/post-update/lerna.spec.ts
index 8115050c2ac9abebd9cb00e0583573bf5b928672..f81d5e535432eb9c7f3dea226899dada59df43c5 100644
--- a/lib/modules/manager/npm/post-update/lerna.spec.ts
+++ b/lib/modules/manager/npm/post-update/lerna.spec.ts
@@ -1,3 +1,4 @@
+import { mockDeep } from 'jest-mock-extended';
 import { envMock, mockExecAll } from '../../../../../test/exec-util';
 import { env, fs, mockedFunction, partial } from '../../../../../test/util';
 import { GlobalConfig } from '../../../../config/global';
@@ -9,7 +10,7 @@ import { getNodeToolConstraint } from './node-version';
 jest.mock('../../../../util/exec/env');
 jest.mock('../../../../util/fs');
 jest.mock('./node-version');
-jest.mock('../../../datasource');
+jest.mock('../../../datasource', () => mockDeep());
 
 process.env.CONTAINERBASE = 'true';
 
@@ -29,8 +30,6 @@ describe('modules/manager/npm/post-update/lerna', () => {
 
   describe('generateLockFiles()', () => {
     beforeEach(() => {
-      jest.resetAllMocks();
-      jest.resetModules();
       env.getChildProcessEnv.mockReturnValue(envMock.basic);
       GlobalConfig.set(globalConfig);
       mockedFunction(getNodeToolConstraint).mockResolvedValueOnce({
diff --git a/lib/modules/manager/npm/post-update/npm.spec.ts b/lib/modules/manager/npm/post-update/npm.spec.ts
index a282620ebee7248b2db4c3161b1fa930f7debdcf..ffa0273a2a84908dc8da9f23e84f73f5af980fd5 100644
--- a/lib/modules/manager/npm/post-update/npm.spec.ts
+++ b/lib/modules/manager/npm/post-update/npm.spec.ts
@@ -14,8 +14,6 @@ process.env.CONTAINERBASE = 'true';
 
 describe('modules/manager/npm/post-update/npm', () => {
   beforeEach(() => {
-    jest.resetAllMocks();
-    jest.resetModules();
     env.getChildProcessEnv.mockReturnValue(envMock.basic);
     GlobalConfig.set({ localDir: '' });
     mockedFunction(getNodeToolConstraint).mockResolvedValueOnce({
diff --git a/lib/modules/manager/npm/post-update/pnpm.spec.ts b/lib/modules/manager/npm/post-update/pnpm.spec.ts
index adf740f2808e762d951d034adc597f7810e22072..064af1bdae74d426730abb3a2c2434db34967a72 100644
--- a/lib/modules/manager/npm/post-update/pnpm.spec.ts
+++ b/lib/modules/manager/npm/post-update/pnpm.spec.ts
@@ -17,7 +17,6 @@ describe('modules/manager/npm/post-update/pnpm', () => {
   let config: PostUpdateConfig;
 
   beforeEach(() => {
-    jest.resetAllMocks();
     config = partial<PostUpdateConfig>({ constraints: { pnpm: '^2.0.0' } });
     env.getChildProcessEnv.mockReturnValue(envMock.basic);
     GlobalConfig.set({ localDir: '' });
diff --git a/lib/modules/manager/npm/post-update/yarn.spec.ts b/lib/modules/manager/npm/post-update/yarn.spec.ts
index 01f25c822a0e37431a88123719ec235caa9ea68b..fb96a054f4d03bb4ba409abcdfa63c7e85572e7d 100644
--- a/lib/modules/manager/npm/post-update/yarn.spec.ts
+++ b/lib/modules/manager/npm/post-update/yarn.spec.ts
@@ -1,4 +1,5 @@
 import fs from 'fs-extra';
+import { mockDeep } from 'jest-mock-extended';
 import {
   ExecSnapshots,
   envMock,
@@ -16,11 +17,15 @@ import { getNodeToolConstraint } from './node-version';
 import * as yarnHelper from './yarn';
 
 jest.mock('fs-extra', () =>
-  require('../../../../../test/fixtures').Fixtures.fsExtra()
+  jest
+    .requireActual<typeof import('../../../../../test/fixtures')>(
+      '../../../../../test/fixtures'
+    )
+    .fsExtra()
 );
 jest.mock('../../../../util/exec/env');
 jest.mock('./node-version');
-jest.mock('../../../datasource');
+jest.mock('../../../datasource', () => mockDeep());
 
 delete process.env.NPM_CONFIG_CACHE;
 
@@ -34,14 +39,16 @@ const fixSnapshots = (snapshots: ExecSnapshots): ExecSnapshots =>
 const plocktest1PackageJson = Fixtures.get('plocktest1/package.json', '..');
 const plocktest1YarnLockV1 = Fixtures.get('plocktest1/yarn.lock', '..');
 
-jest.spyOn(docker, 'removeDockerContainer').mockResolvedValue();
 env.getChildProcessEnv.mockReturnValue(envMock.basic);
 
 describe('modules/manager/npm/post-update/yarn', () => {
+  const removeDockerContainer = jest.spyOn(docker, 'removeDockerContainer');
+
   beforeEach(() => {
     delete process.env.BUILDPACK;
     Fixtures.reset();
     GlobalConfig.set({ localDir: '.', cacheDir: '/tmp/cache' });
+    removeDockerContainer.mockResolvedValue();
     docker.resetPrefetchedImages();
     mockedFunction(getNodeToolConstraint).mockResolvedValueOnce({
       toolName: 'node',
diff --git a/lib/modules/manager/npm/update/package-version/index.spec.ts b/lib/modules/manager/npm/update/package-version/index.spec.ts
index 53829adc47b389075aad45d63040f05d49f42291..e40b5fb14873704e28d9fe526fbf1f45c5a81f4a 100644
--- a/lib/modules/manager/npm/update/package-version/index.spec.ts
+++ b/lib/modules/manager/npm/update/package-version/index.spec.ts
@@ -57,7 +57,7 @@ describe('modules/manager/npm/update/package-version/index', () => {
     });
 
     it('returns content if bumping errors', async () => {
-      jest.mock('semver', () => ({
+      jest.doMock('semver', () => ({
         inc: () => {
           throw new Error('semver inc');
         },
diff --git a/lib/modules/manager/nuget/artifacts.spec.ts b/lib/modules/manager/nuget/artifacts.spec.ts
index 9d72b820fcab63f00b4e2e9371cd26967b82c373..a0fbeb9f30a0e3e5df2ed1f28b3316ab79718a02 100644
--- a/lib/modules/manager/nuget/artifacts.spec.ts
+++ b/lib/modules/manager/nuget/artifacts.spec.ts
@@ -1,3 +1,4 @@
+import { mockDeep } from 'jest-mock-extended';
 import { join } from 'upath';
 import { envMock, mockExecAll } from '../../../../test/exec-util';
 import { env, fs, git, mocked, scm } from '../../../../test/util';
@@ -12,16 +13,13 @@ import * as nuget from '.';
 
 jest.mock('../../../util/exec/env');
 jest.mock('../../../util/fs');
-jest.mock('../../../util/host-rules');
+jest.mock('../../../util/host-rules', () => mockDeep());
 jest.mock('../../../util/git');
 jest.mock('./util');
 
 const { getConfiguredRegistries, getDefaultRegistries } = mocked(util);
 const hostRules = mocked(_hostRules);
 
-const realFs =
-  jest.requireActual<typeof import('../../../util/fs')>('../../../util/fs');
-
 process.env.CONTAINERBASE = 'true';
 
 const adminConfig: RepoGlobalConfig = {
@@ -35,8 +33,8 @@ const config: UpdateArtifactsConfig = {};
 
 describe('modules/manager/nuget/artifacts', () => {
   beforeEach(() => {
-    jest.resetAllMocks();
-    jest.resetModules();
+    const realFs =
+      jest.requireActual<typeof import('../../../util/fs')>('../../../util/fs');
     getDefaultRegistries.mockReturnValue([]);
     env.getChildProcessEnv.mockReturnValue(envMock.basic);
     fs.privateCacheDir.mockImplementation(realFs.privateCacheDir);
diff --git a/lib/modules/manager/nuget/package-tree.spec.ts b/lib/modules/manager/nuget/package-tree.spec.ts
index 3b9e99e04c860e370a29a728bfd04237c8d58276..ab210f02478a942ccbb75b3b3461944b975f5756 100644
--- a/lib/modules/manager/nuget/package-tree.spec.ts
+++ b/lib/modules/manager/nuget/package-tree.spec.ts
@@ -7,7 +7,13 @@ import type { RepoGlobalConfig } from '../../../config/types';
 import { getDependentPackageFiles } from './package-tree';
 
 jest.mock('fs', () => memfs);
-jest.mock('fs-extra', () => Fixtures.fsExtra());
+jest.mock('fs-extra', () =>
+  jest
+    .requireActual<typeof import('../../../../test/fixtures')>(
+      '../../../../test/fixtures'
+    )
+    .fsExtra()
+);
 jest.mock('../../../util/git');
 
 const adminConfig: RepoGlobalConfig = {
diff --git a/lib/modules/manager/pep621/artifacts.spec.ts b/lib/modules/manager/pep621/artifacts.spec.ts
index a5b8fcd55a028b6915bbc77dc9cb0488450dc58d..c3c3b9bd1bd89da1e2882615198042b70a44cf68 100644
--- a/lib/modules/manager/pep621/artifacts.spec.ts
+++ b/lib/modules/manager/pep621/artifacts.spec.ts
@@ -1,4 +1,5 @@
 import { codeBlock } from 'common-tags';
+import { mockDeep } from 'jest-mock-extended';
 import { join } from 'upath';
 import { mockExecAll } from '../../../../test/exec-util';
 import { fs, mockedFunction } from '../../../../test/util';
@@ -9,7 +10,7 @@ import type { UpdateArtifactsConfig } from '../types';
 import { updateArtifacts } from './artifacts';
 
 jest.mock('../../../util/fs');
-jest.mock('../../datasource');
+jest.mock('../../datasource', () => mockDeep());
 
 const getPkgReleases = mockedFunction(_getPkgReleases);
 
diff --git a/lib/modules/manager/pip-compile/artifacts.spec.ts b/lib/modules/manager/pip-compile/artifacts.spec.ts
index a9fc034e8425f2aabdb5471d67321c70b6ffd194..350a88030de5ad5adbfa5499151789166231f61b 100644
--- a/lib/modules/manager/pip-compile/artifacts.spec.ts
+++ b/lib/modules/manager/pip-compile/artifacts.spec.ts
@@ -1,3 +1,4 @@
+import { mockDeep } from 'jest-mock-extended';
 import { join } from 'upath';
 import { envMock, mockExecAll } from '../../../../test/exec-util';
 import { Fixtures } from '../../../../test/fixtures';
@@ -17,9 +18,9 @@ const datasource = mocked(_datasource);
 jest.mock('../../../util/exec/env');
 jest.mock('../../../util/fs');
 jest.mock('../../../util/git');
-jest.mock('../../../util/host-rules');
+jest.mock('../../../util/host-rules', () => mockDeep());
 jest.mock('../../../util/http');
-jest.mock('../../datasource');
+jest.mock('../../datasource', () => mockDeep());
 
 const adminConfig: RepoGlobalConfig = {
   // `join` fixes Windows CI
@@ -40,7 +41,6 @@ const lockMaintenanceConfig = { ...config, isLockFileMaintenance: true };
 
 describe('modules/manager/pip-compile/artifacts', () => {
   beforeEach(() => {
-    jest.resetAllMocks();
     env.getChildProcessEnv.mockReturnValue({
       ...envMock.basic,
       LANG: 'en_US.UTF-8',
diff --git a/lib/modules/manager/pip_requirements/artifacts.spec.ts b/lib/modules/manager/pip_requirements/artifacts.spec.ts
index 78ed52537de46788d42e94b3c6bc5142985fea1e..314a591e70d997ec196bee6cef6ccd969b7f1691 100644
--- a/lib/modules/manager/pip_requirements/artifacts.spec.ts
+++ b/lib/modules/manager/pip_requirements/artifacts.spec.ts
@@ -1,3 +1,4 @@
+import { mockDeep } from 'jest-mock-extended';
 import { join } from 'upath';
 import { mockExecAll } from '../../../../test/exec-util';
 import { fs, mocked } from '../../../../test/util';
@@ -11,7 +12,7 @@ const datasource = mocked(_datasource);
 
 jest.mock('../../../util/exec/common');
 jest.mock('../../../util/fs');
-jest.mock('../../datasource');
+jest.mock('../../datasource', () => mockDeep());
 
 process.env.CONTAINERBASE = 'true';
 
@@ -41,8 +42,6 @@ botocore==1.27.46 \
 
 describe('modules/manager/pip_requirements/artifacts', () => {
   beforeEach(() => {
-    jest.resetAllMocks();
-    jest.resetModules();
     GlobalConfig.set(adminConfig);
   });
 
diff --git a/lib/modules/manager/pipenv/artifacts.spec.ts b/lib/modules/manager/pipenv/artifacts.spec.ts
index 97659619601515ead83abd6985fa3de471d7d452..2ecfd2d2b4900df1996b0fa727e14ab37160dafb 100644
--- a/lib/modules/manager/pipenv/artifacts.spec.ts
+++ b/lib/modules/manager/pipenv/artifacts.spec.ts
@@ -1,3 +1,4 @@
+import { mockDeep } from 'jest-mock-extended';
 import { join } from 'upath';
 import { envMock, mockExecAll } from '../../../../test/exec-util';
 import {
@@ -22,9 +23,9 @@ const datasource = mocked(_datasource);
 jest.mock('../../../util/exec/env');
 jest.mock('../../../util/git');
 jest.mock('../../../util/fs');
-jest.mock('../../../util/host-rules');
+jest.mock('../../../util/host-rules', () => mockDeep());
 jest.mock('../../../util/http');
-jest.mock('../../datasource');
+jest.mock('../../datasource', () => mockDeep());
 
 process.env.CONTAINERBASE = 'true';
 
@@ -50,7 +51,6 @@ describe('modules/manager/pipenv/artifacts', () => {
   let pipFileLock: any;
 
   beforeEach(() => {
-    jest.resetAllMocks();
     env.getChildProcessEnv.mockReturnValue({
       ...envMock.basic,
       LANG: 'en_US.UTF-8',
diff --git a/lib/modules/manager/poetry/artifacts.spec.ts b/lib/modules/manager/poetry/artifacts.spec.ts
index 72d2f8023a15e64d5385d3a4858a0885edf66a42..1bd44b1c4a7dbb017e9b12a6d3a2a9e32c464d77 100644
--- a/lib/modules/manager/poetry/artifacts.spec.ts
+++ b/lib/modules/manager/poetry/artifacts.spec.ts
@@ -1,3 +1,4 @@
+import { mockDeep } from 'jest-mock-extended';
 import { join } from 'upath';
 import { envMock, mockExecAll } from '../../../../test/exec-util';
 import { Fixtures } from '../../../../test/fixtures';
@@ -16,8 +17,8 @@ const pyproject10toml = Fixtures.get('pyproject.10.toml');
 
 jest.mock('../../../util/exec/env');
 jest.mock('../../../util/fs');
-jest.mock('../../datasource');
-jest.mock('../../../util/host-rules');
+jest.mock('../../datasource', () => mockDeep());
+jest.mock('../../../util/host-rules', () => mockDeep());
 
 process.env.CONTAINERBASE = 'true';
 
@@ -54,7 +55,6 @@ describe('modules/manager/poetry/artifacts', () => {
 
   describe('updateArtifacts', () => {
     beforeEach(() => {
-      jest.resetAllMocks();
       env.getChildProcessEnv.mockReturnValue(envMock.basic);
       GlobalConfig.set(adminConfig);
       docker.resetPrefetchedImages();
diff --git a/lib/modules/manager/pre-commit/extract.spec.ts b/lib/modules/manager/pre-commit/extract.spec.ts
index 73d8d7d8d104a0b027fbafca91e366128b4ccebb..cefbcfc63275a21e5325200dd319a622785baf99 100644
--- a/lib/modules/manager/pre-commit/extract.spec.ts
+++ b/lib/modules/manager/pre-commit/extract.spec.ts
@@ -1,9 +1,10 @@
+import { mockDeep } from 'jest-mock-extended';
 import { Fixtures } from '../../../../test/fixtures';
 import { mocked } from '../../../../test/util';
 import * as _hostRules from '../../../util/host-rules';
 import { extractPackageFile } from '.';
 
-jest.mock('../../../util/host-rules');
+jest.mock('../../../util/host-rules', () => mockDeep());
 const hostRules = mocked(_hostRules);
 const filename = '.pre-commit.yaml';
 
@@ -22,10 +23,6 @@ const enterpriseGitPrecommitConfig = Fixtures.get(
 
 describe('modules/manager/pre-commit/extract', () => {
   describe('extractPackageFile()', () => {
-    beforeEach(() => {
-      jest.resetAllMocks();
-    });
-
     it('returns null for invalid yaml file content', () => {
       const result = extractPackageFile('nothing here: [', filename);
       expect(result).toBeNull();
diff --git a/lib/modules/manager/pub/artifacts.spec.ts b/lib/modules/manager/pub/artifacts.spec.ts
index e291049d1b0fa4b6adcb002b70e5490bdda85e32..762158dade532baa7263475bf87cd6502967cd22 100644
--- a/lib/modules/manager/pub/artifacts.spec.ts
+++ b/lib/modules/manager/pub/artifacts.spec.ts
@@ -1,4 +1,5 @@
 import { codeBlock } from 'common-tags';
+import { mockDeep } from 'jest-mock-extended';
 import { join } from 'upath';
 import { envMock, mockExecAll } from '../../../../test/exec-util';
 import { env, fs, mocked } from '../../../../test/util';
@@ -13,7 +14,7 @@ jest.mock('../../../util/exec/env');
 jest.mock('../../../util/fs');
 jest.mock('../../../util/git');
 jest.mock('../../../util/http');
-jest.mock('../../datasource');
+jest.mock('../../datasource', () => mockDeep());
 
 process.env.CONTAINERBASE = 'true';
 
@@ -45,8 +46,6 @@ const updateArtifact: UpdateArtifact = {
 
 describe('modules/manager/pub/artifacts', () => {
   beforeEach(() => {
-    jest.resetAllMocks();
-
     env.getChildProcessEnv.mockReturnValue(envMock.basic);
     GlobalConfig.set(adminConfig);
     docker.resetPrefetchedImages();
diff --git a/lib/modules/manager/terraform/lockfile/hash.spec.ts b/lib/modules/manager/terraform/lockfile/hash.spec.ts
index 6f123877f285519177ef53623e31c3f398f471fd..149d0e2291899e5f2f20e3ae241997fbe964c60c 100644
--- a/lib/modules/manager/terraform/lockfile/hash.spec.ts
+++ b/lib/modules/manager/terraform/lockfile/hash.spec.ts
@@ -4,14 +4,13 @@ import { Fixtures } from '../../../../../test/fixtures';
 import * as httpMock from '../../../../../test/http-mock';
 import { getFixturePath, logger } from '../../../../../test/util';
 import { GlobalConfig } from '../../../../config/global';
-import type { Logger } from '../../../../logger/types';
 import { TerraformProviderDatasource } from '../../../datasource/terraform-provider';
 import { TerraformProviderHash } from './hash';
 
 const releaseBackendUrl = TerraformProviderDatasource.defaultRegistryUrls[1];
 const releaseBackendAzurerm = Fixtures.get('releaseBackendAzurerm_2_56_0.json');
 
-const log = logger.logger as jest.Mocked<Logger>;
+const log = logger.logger;
 
 describe('modules/manager/terraform/lockfile/hash', () => {
   let cacheDir: DirectoryResult;
diff --git a/lib/modules/manager/terraform/lockfile/index.spec.ts b/lib/modules/manager/terraform/lockfile/index.spec.ts
index 75e4c93c48a15715deacc9fbaa741801c2e14134..a04fbd3602eac2fe4d6872f06734632f0f44fc37 100644
--- a/lib/modules/manager/terraform/lockfile/index.spec.ts
+++ b/lib/modules/manager/terraform/lockfile/index.spec.ts
@@ -1,3 +1,4 @@
+import { mockDeep } from 'jest-mock-extended';
 import { join } from 'upath';
 import { Fixtures } from '../../../../../test/fixtures';
 import { fs, mocked } from '../../../../../test/util';
@@ -10,7 +11,7 @@ import { TerraformProviderHash } from './hash';
 // auto-mock fs
 jest.mock('../../../../util/fs');
 jest.mock('./hash');
-jest.mock('../../../datasource');
+jest.mock('../../../datasource', () => mockDeep());
 
 const config = {
   constraints: {},
@@ -33,8 +34,6 @@ const mockGetPkgReleases = getPkgReleases as jest.MockedFunction<
 
 describe('modules/manager/terraform/lockfile/index', () => {
   beforeEach(() => {
-    jest.resetAllMocks();
-    jest.resetModules();
     GlobalConfig.set(adminConfig);
   });
 
diff --git a/lib/modules/platform/azure/azure-got-wrapper.spec.ts b/lib/modules/platform/azure/azure-got-wrapper.spec.ts
index 6b8498e378b1a1e87f3c49eddfffdef549bd0df5..57c21e0a0d9e783e6b32b94aa1972fb60af8ba30 100644
--- a/lib/modules/platform/azure/azure-got-wrapper.spec.ts
+++ b/lib/modules/platform/azure/azure-got-wrapper.spec.ts
@@ -4,11 +4,11 @@ describe('modules/platform/azure/azure-got-wrapper', () => {
   let azure: typeof import('./azure-got-wrapper');
   let hostRules: typeof _hostRules;
 
-  beforeEach(() => {
+  beforeEach(async () => {
     // reset module
     jest.resetModules();
-    hostRules = require('../../../util/host-rules');
-    azure = require('./azure-got-wrapper');
+    hostRules = await import('../../../util/host-rules');
+    azure = await import('./azure-got-wrapper');
   });
 
   describe('gitApi', () => {
diff --git a/lib/modules/platform/azure/azure-helper.spec.ts b/lib/modules/platform/azure/azure-helper.spec.ts
index 2a94b6b652b7379bdb62e1fcca9f820bedd7ffc8..d1cb1a939ad640e33b867cb1c22796afbc1c5df6 100644
--- a/lib/modules/platform/azure/azure-helper.spec.ts
+++ b/lib/modules/platform/azure/azure-helper.spec.ts
@@ -1,16 +1,17 @@
 import { Readable } from 'node:stream';
 import { GitPullRequestMergeStrategy } from 'azure-devops-node-api/interfaces/GitInterfaces.js';
 
+jest.mock('./azure-got-wrapper');
+
 describe('modules/platform/azure/azure-helper', () => {
   let azureHelper: typeof import('./azure-helper');
   let azureApi: jest.Mocked<typeof import('./azure-got-wrapper')>;
 
-  beforeEach(() => {
+  beforeEach(async () => {
     // reset module
     jest.resetModules();
-    jest.mock('./azure-got-wrapper');
-    azureHelper = require('./azure-helper');
-    azureApi = require('./azure-got-wrapper');
+    azureHelper = await import('./azure-helper');
+    azureApi = jest.requireMock('./azure-got-wrapper');
   });
 
   describe('getRef', () => {
diff --git a/lib/modules/platform/azure/index.spec.ts b/lib/modules/platform/azure/index.spec.ts
index 3c99d2dff05f17ee21a17a648ab8ddcdc9c06b16..bc8ea958dad609b6c7ddb6ace016b9391415c683 100644
--- a/lib/modules/platform/azure/index.spec.ts
+++ b/lib/modules/platform/azure/index.spec.ts
@@ -6,7 +6,8 @@ import {
   GitStatusState,
   PullRequestStatus,
 } from 'azure-devops-node-api/interfaces/GitInterfaces.js';
-import { partial } from '../../../../test/util';
+import { mockDeep } from 'jest-mock-extended';
+import { mocked, partial } from '../../../../test/util';
 import {
   REPOSITORY_ARCHIVED,
   REPOSITORY_NOT_FOUND,
@@ -17,30 +18,32 @@ import type * as _hostRules from '../../../util/host-rules';
 import type { Platform, RepoParams } from '../types';
 import { AzurePrVote } from './types';
 
+jest.mock('./azure-got-wrapper');
+jest.mock('./azure-helper');
+jest.mock('../../../util/git');
+jest.mock('../../../util/host-rules', () => mockDeep());
+jest.mock('../../../util/sanitize', () =>
+  mockDeep({ sanitize: (s: string) => s })
+);
+jest.mock('timers/promises');
+
 describe('modules/platform/azure/index', () => {
   let hostRules: jest.Mocked<typeof _hostRules>;
   let azure: Platform;
   let azureApi: jest.Mocked<typeof import('./azure-got-wrapper')>;
   let azureHelper: jest.Mocked<typeof import('./azure-helper')>;
   let git: jest.Mocked<typeof _git>;
-  let logger: jest.Mocked<typeof _logger>;
+  let logger: jest.MockedObject<typeof _logger>;
 
   beforeEach(async () => {
     // reset module
     jest.resetModules();
-    jest.mock('./azure-got-wrapper');
-    jest.mock('./azure-helper');
-    jest.mock('../../../util/git');
-    jest.mock('../../../util/host-rules');
-    jest.mock('../../../logger');
-    jest.mock('timers/promises');
-    hostRules = require('../../../util/host-rules');
-    require('../../../util/sanitize').sanitize = jest.fn((input) => input);
+    hostRules = jest.requireMock('../../../util/host-rules');
     azure = await import('.');
-    azureApi = require('./azure-got-wrapper');
-    azureHelper = require('./azure-helper');
-    logger = (await import('../../../logger')).logger as never;
-    git = require('../../../util/git');
+    azureApi = jest.requireMock('./azure-got-wrapper');
+    azureHelper = jest.requireMock('./azure-helper');
+    logger = mocked(await import('../../../logger')).logger;
+    git = jest.requireMock('../../../util/git');
     git.branchExists.mockReturnValue(true);
     git.isBranchBehindBase.mockResolvedValue(false);
     hostRules.find.mockReturnValue({
diff --git a/lib/modules/platform/bitbucket-server/index.spec.ts b/lib/modules/platform/bitbucket-server/index.spec.ts
index f2b5f4357a2b8dbddf19ddd91f691ddd58434bd0..9084bb165cdc4399aa409ae36f63a5ad0336ae21 100644
--- a/lib/modules/platform/bitbucket-server/index.spec.ts
+++ b/lib/modules/platform/bitbucket-server/index.spec.ts
@@ -1,4 +1,5 @@
 import is from '@sindresorhus/is';
+import { mockDeep } from 'jest-mock-extended';
 import * as httpMock from '../../../../test/http-mock';
 import {
   REPOSITORY_CHANGED,
@@ -8,6 +9,10 @@ import {
 import type * as _git from '../../../util/git';
 import type { Platform } from '../types';
 
+jest.mock('timers/promises');
+jest.mock('../../../util/git');
+jest.mock('../../../util/host-rules', () => mockDeep());
+
 function sshLink(projectKey: string, repositorySlug: string): string {
   return `ssh://git@stash.renovatebot.com:7999/${projectKey.toLowerCase()}/${repositorySlug}.git`;
 }
@@ -167,6 +172,8 @@ const scenarios = {
   'endpoint with path': new URL('https://stash.renovatebot.com/vcs'),
 };
 
+type HostRules = typeof import('../../../util/host-rules');
+
 describe('modules/platform/bitbucket-server/index', () => {
   Object.entries(scenarios).forEach(([scenarioName, url]) => {
     const urlHost = url.origin;
@@ -174,7 +181,8 @@ describe('modules/platform/bitbucket-server/index', () => {
 
     describe(scenarioName, () => {
       let bitbucket: Platform;
-      let hostRules: jest.Mocked<typeof import('../../../util/host-rules')>;
+
+      let hostRules: jest.Mocked<HostRules>;
       let git: jest.Mocked<typeof _git>;
       const username = 'abc';
       const password = '123';
@@ -201,12 +209,9 @@ describe('modules/platform/bitbucket-server/index', () => {
       beforeEach(async () => {
         // reset module
         jest.resetModules();
-        jest.mock('timers/promises');
-        jest.mock('../../../util/git');
-        jest.mock('../../../util/host-rules');
-        hostRules = require('../../../util/host-rules');
         bitbucket = await import('.');
-        git = require('../../../util/git');
+        hostRules = jest.requireMock('../../../util/host-rules');
+        git = jest.requireMock('../../../util/git');
         git.branchExists.mockReturnValue(true);
         git.isBranchBehindBase.mockResolvedValue(false);
         git.getBranchCommit.mockReturnValue(
diff --git a/lib/modules/platform/bitbucket/index.spec.ts b/lib/modules/platform/bitbucket/index.spec.ts
index 603bb2b5e91c861e0d82bcb189514edaa1be8dfc..5070c067247f2c83e5cfe7591e20f00916af6d12 100644
--- a/lib/modules/platform/bitbucket/index.spec.ts
+++ b/lib/modules/platform/bitbucket/index.spec.ts
@@ -4,6 +4,9 @@ import type * as _git from '../../../util/git';
 import { setBaseUrl } from '../../../util/http/bitbucket';
 import type { Platform, PlatformResult, RepoParams } from '../types';
 
+jest.mock('../../../util/git');
+jest.mock('../../../util/host-rules');
+
 const baseUrl = 'https://api.bitbucket.org';
 
 const pr = {
@@ -25,13 +28,10 @@ describe('modules/platform/bitbucket/index', () => {
   beforeEach(async () => {
     // reset module
     jest.resetModules();
-    jest.mock('../../../util/git');
-    jest.mock('../../../util/host-rules');
-    jest.mock('../../../logger');
-    hostRules = require('../../../util/host-rules');
+    hostRules = jest.requireMock('../../../util/host-rules');
     bitbucket = await import('.');
     logger = (await import('../../../logger')).logger as any;
-    git = require('../../../util/git');
+    git = jest.requireMock('../../../util/git');
     git.branchExists.mockReturnValue(true);
     git.isBranchBehindBase.mockResolvedValue(false);
     // clean up hostRules
diff --git a/lib/modules/platform/comment.spec.ts b/lib/modules/platform/comment.spec.ts
index 58fa3406eab9f3a28ab3eb51ba01642390040554..54a7116b3a5dc81278ca50ba3cddc5ccc49f796a 100644
--- a/lib/modules/platform/comment.spec.ts
+++ b/lib/modules/platform/comment.spec.ts
@@ -13,7 +13,7 @@ describe('modules/platform/comment', () => {
 
   beforeEach(() => {
     repoCache = {};
-    jest.resetAllMocks();
+
     cache.getCache.mockReturnValue(repoCache);
   });
 
diff --git a/lib/modules/platform/gitea/gitea-helper.spec.ts b/lib/modules/platform/gitea/gitea-helper.spec.ts
index 098699d88a977e48d2f043dd7d3479e1fe32f966..d1cd25298332ecc926332611304edb2bbb4582d3 100644
--- a/lib/modules/platform/gitea/gitea-helper.spec.ts
+++ b/lib/modules/platform/gitea/gitea-helper.spec.ts
@@ -184,7 +184,6 @@ describe('modules/platform/gitea/gitea-helper', () => {
   };
 
   beforeEach(() => {
-    jest.resetAllMocks();
     setBaseUrl(giteaApiHost);
   });
 
diff --git a/lib/modules/platform/gitea/index.spec.ts b/lib/modules/platform/gitea/index.spec.ts
index ce8604ed61ebec8909f0b040be39f2efa696c52f..140925dec6e1cd93a79664e742b5deeee462968e 100644
--- a/lib/modules/platform/gitea/index.spec.ts
+++ b/lib/modules/platform/gitea/index.spec.ts
@@ -35,6 +35,9 @@ import type {
   User,
 } from './types';
 
+jest.mock('./gitea-helper');
+jest.mock('../../../util/git');
+
 /**
  * latest tested gitea version.
  */
@@ -45,7 +48,7 @@ describe('modules/platform/gitea/index', () => {
   let helper: jest.Mocked<typeof import('./gitea-helper')>;
   let logger: jest.Mocked<typeof _logger>;
   let gitvcs: jest.Mocked<typeof _git>;
-  let hostRules: jest.Mocked<typeof import('../../../util/host-rules')>;
+  let hostRules: typeof import('../../../util/host-rules');
 
   const mockCommitHash = '0d9c7726c3d628b7e28af234595cfd20febdbf8e';
 
@@ -199,17 +202,14 @@ describe('modules/platform/gitea/index', () => {
 
   beforeEach(async () => {
     jest.resetModules();
-    jest.mock('./gitea-helper');
-    jest.mock('../../../util/git');
-    jest.mock('../../../logger');
 
     gitea = await import('.');
-    helper = mocked(await import('./gitea-helper'));
-    logger = mocked((await import('../../../logger')).logger);
-    gitvcs = require('../../../util/git');
+    helper = jest.requireMock('./gitea-helper');
+    logger = mocked(await import('../../../logger')).logger;
+    gitvcs = jest.requireMock('../../../util/git');
     gitvcs.isBranchBehindBase.mockResolvedValue(false);
     gitvcs.getBranchCommit.mockReturnValue(mockCommitHash);
-    hostRules = mocked(await import('../../../util/host-rules'));
+    hostRules = await import('../../../util/host-rules');
     hostRules.clear();
 
     setBaseUrl('https://gitea.renovatebot.com/');
diff --git a/lib/modules/platform/github/index.spec.ts b/lib/modules/platform/github/index.spec.ts
index b08a7c13a3264534947c779deeac71d4a1da2ef4..0a5cdbc72d35daa4918e67c4464de6092681f6b3 100644
--- a/lib/modules/platform/github/index.spec.ts
+++ b/lib/modules/platform/github/index.spec.ts
@@ -1,3 +1,4 @@
+import { mockDeep } from 'jest-mock-extended';
 import { DateTime } from 'luxon';
 import * as httpMock from '../../../../test/http-mock';
 import { logger, mocked, partial } from '../../../../test/util';
@@ -24,7 +25,7 @@ const githubApiHost = 'https://api.github.com';
 
 jest.mock('timers/promises');
 
-jest.mock('../../../util/host-rules');
+jest.mock('../../../util/host-rules', () => mockDeep());
 jest.mock('../../../util/http/queue');
 const hostRules: jest.Mocked<typeof _hostRules> = mocked(_hostRules);
 
@@ -33,7 +34,6 @@ const git: jest.Mocked<typeof _git> = mocked(_git);
 
 describe('modules/platform/github/index', () => {
   beforeEach(() => {
-    jest.resetAllMocks();
     github.resetConfigs();
 
     setBaseUrl(githubApiHost);
diff --git a/lib/modules/platform/gitlab/index.spec.ts b/lib/modules/platform/gitlab/index.spec.ts
index 047f14dac5ce02ad057f1f951f1a41f9692a7182..f6f9e32203e09bb83e2088d7190be4a6c4844d28 100644
--- a/lib/modules/platform/gitlab/index.spec.ts
+++ b/lib/modules/platform/gitlab/index.spec.ts
@@ -1,7 +1,9 @@
 // TODO fix mocks
 import type * as _timers from 'timers/promises';
+import { mockDeep } from 'jest-mock-extended';
 import type { Platform, RepoParams } from '..';
 import * as httpMock from '../../../../test/http-mock';
+import { mocked } from '../../../../test/util';
 import {
   CONFIG_GIT_URL_UNAVAILABLE,
   REPOSITORY_ARCHIVED,
@@ -16,6 +18,10 @@ import type * as _git from '../../../util/git';
 import type * as _hostRules from '../../../util/host-rules';
 import { toBase64 } from '../../../util/string';
 
+jest.mock('../../../util/host-rules', () => mockDeep());
+jest.mock('../../../util/git');
+jest.mock('timers/promises');
+
 const gitlabApiHost = 'https://gitlab.com';
 
 describe('modules/platform/gitlab/index', () => {
@@ -28,16 +34,12 @@ describe('modules/platform/gitlab/index', () => {
   beforeEach(async () => {
     // reset module
     jest.resetModules();
-    jest.resetAllMocks();
+
     gitlab = await import('.');
-    jest.mock('../../../logger');
-    logger = (await import('../../../logger')).logger as never;
-    jest.mock('../../../util/host-rules');
-    jest.mock('timers/promises');
-    timers = require('timers/promises');
-    hostRules = require('../../../util/host-rules');
-    jest.mock('../../../util/git');
-    git = require('../../../util/git');
+    logger = mocked(await import('../../../logger')).logger;
+    timers = jest.requireMock('timers/promises');
+    hostRules = jest.requireMock('../../../util/host-rules');
+    git = jest.requireMock('../../../util/git');
     git.branchExists.mockReturnValue(true);
     git.isBranchBehindBase.mockResolvedValue(true);
     git.getBranchCommit.mockReturnValue(
@@ -2295,8 +2297,6 @@ describe('modules/platform/gitlab/index', () => {
   });
 
   describe('updatePr(prNo, title, body)', () => {
-    jest.resetAllMocks();
-
     it('updates the PR', async () => {
       await initPlatform('13.3.6-ee');
       httpMock
@@ -2452,8 +2452,6 @@ describe('modules/platform/gitlab/index', () => {
   });
 
   describe('mergePr(pr)', () => {
-    jest.resetAllMocks();
-
     it('merges the PR', async () => {
       httpMock
         .scope(gitlabApiHost)
@@ -2499,8 +2497,8 @@ These updates have all been created already. Click a checkbox below to force a r
     });
 
     it('returns updated pr body', async () => {
-      jest.mock('../utils/pr-body');
-      const { smartTruncate } = require('../utils/pr-body');
+      jest.doMock('../utils/pr-body');
+      const { smartTruncate } = await import('../utils/pr-body');
 
       await initFakePlatform('13.4.0');
       expect(gitlab.massageMarkdown(prBody)).toMatchSnapshot();
@@ -2508,8 +2506,8 @@ These updates have all been created already. Click a checkbox below to force a r
     });
 
     it('truncates description if too low API version', async () => {
-      jest.mock('../utils/pr-body');
-      const { smartTruncate } = require('../utils/pr-body');
+      jest.doMock('../utils/pr-body');
+      const { smartTruncate } = await import('../utils/pr-body');
 
       await initFakePlatform('13.3.0');
       gitlab.massageMarkdown(prBody);
@@ -2518,8 +2516,8 @@ These updates have all been created already. Click a checkbox below to force a r
     });
 
     it('truncates description for API version gt 13.4', async () => {
-      jest.mock('../utils/pr-body');
-      const { smartTruncate } = require('../utils/pr-body');
+      jest.doMock('../utils/pr-body');
+      const { smartTruncate } = await import('../utils/pr-body');
 
       await initFakePlatform('13.4.1');
       gitlab.massageMarkdown(prBody);
diff --git a/lib/modules/platform/local/scm.spec.ts b/lib/modules/platform/local/scm.spec.ts
index 92efed3cf54760d915057a099238f78ce52a4467..2b5b0c12ca4d41850cd01b86ab23ac26589e58ff 100644
--- a/lib/modules/platform/local/scm.spec.ts
+++ b/lib/modules/platform/local/scm.spec.ts
@@ -2,6 +2,9 @@ import { execSync as _execSync } from 'node:child_process';
 import { mockedFunction } from '../../../../test/util';
 import { LocalFs } from './scm';
 
+jest.mock('glob', () => ({
+  glob: jest.fn().mockImplementation(() => Promise.resolve(['file1', 'file2'])),
+}));
 jest.mock('node:child_process');
 const execSync = mockedFunction(_execSync);
 
@@ -56,11 +59,6 @@ describe('modules/platform/local/scm', () => {
       execSync.mockImplementationOnce(() => {
         throw new Error();
       });
-      jest.mock('glob', () => ({
-        glob: jest
-          .fn()
-          .mockImplementation(() => Promise.resolve(['file1', 'file2'])),
-      }));
 
       expect(await localFs.getFileList()).toHaveLength(2);
     });
diff --git a/lib/modules/versioning/index.spec.ts b/lib/modules/versioning/index.spec.ts
index 017d198e1b4af1a2b43907d6e6f13ea0f6581e78..a31f24ce94e6cab6bdb0cd142172166f4dbf9a2f 100644
--- a/lib/modules/versioning/index.spec.ts
+++ b/lib/modules/versioning/index.spec.ts
@@ -106,7 +106,7 @@ describe('modules/versioning/index', () => {
     }
 
     for (const supportedScheme of supportedSchemes ?? []) {
-      it(supportedScheme, () => {
+      it(supportedScheme, async () => {
         const schemeKeys = getAllPropertyNames(
           allVersioning.get(supportedScheme)
         )
@@ -117,7 +117,7 @@ describe('modules/versioning/index', () => {
 
         expect(schemeKeys).toEqual(npmApi);
 
-        const apiOrCtor = require('./' + supportedScheme).api;
+        const apiOrCtor = (await import(`./${supportedScheme}`)).api;
         if (isVersioningApiConstructor(apiOrCtor)) {
           return;
         }
diff --git a/lib/modules/versioning/ubuntu/index.spec.ts b/lib/modules/versioning/ubuntu/index.spec.ts
index 116828621d77d221b64442d7d1f8e3bf51d6b6f5..e2c56b97277283f5333d321e49084c27c22dc355 100644
--- a/lib/modules/versioning/ubuntu/index.spec.ts
+++ b/lib/modules/versioning/ubuntu/index.spec.ts
@@ -4,10 +4,6 @@ import { api as ubuntu } from '.';
 describe('modules/versioning/ubuntu/index', () => {
   const dt = DateTime.fromISO('2022-04-20');
 
-  afterEach(() => {
-    jest.resetAllMocks();
-  });
-
   it.each`
     version        | expected
     ${undefined}   | ${false}
diff --git a/lib/modules/versioning/versioning-metadata.spec.ts b/lib/modules/versioning/versioning-metadata.spec.ts
index ae5c1722df2b78e9b5b4cdb03a797fdbd010be8d..28cfda606ea522a775e1e9beed6161e8b3da12bd 100644
--- a/lib/modules/versioning/versioning-metadata.spec.ts
+++ b/lib/modules/versioning/versioning-metadata.spec.ts
@@ -28,7 +28,7 @@ describe('modules/versioning/versioning-metadata', () => {
     );
 
     for (const versioning of allVersioning) {
-      const versioningObj = require(`./${versioning}`);
+      const versioningObj = await import(`./${versioning}`);
       expect(versioningObj.id).toEqual(versioning);
       expect(versioningObj.displayName).toBeDefined();
       expect(versioningObj.urls).toBeDefined();
diff --git a/lib/renovate.spec.ts b/lib/renovate.spec.ts
index 6df1d8b232b693d3fe489112bc29ed2f9b0b0a17..58efd7dcffecccc69ec1439c9e2c15882c3a6759 100644
--- a/lib/renovate.spec.ts
+++ b/lib/renovate.spec.ts
@@ -3,8 +3,8 @@ import * as renovateWorker from './workers/global';
 Object.defineProperty(renovateWorker, 'start', { value: jest.fn() });
 
 describe('renovate', () => {
-  it('starts', () => {
-    require('./renovate');
+  it('starts', async () => {
+    await import('./renovate');
     expect(renovateWorker.start).toHaveBeenCalledTimes(1);
   });
 });
diff --git a/lib/util/cache/package/decorator.spec.ts b/lib/util/cache/package/decorator.spec.ts
index e3d5de83da191255589c79f43c59a1eb77c89a9c..eb5d33312160acfa82de4a370cd0a23f67287e88 100644
--- a/lib/util/cache/package/decorator.spec.ts
+++ b/lib/util/cache/package/decorator.spec.ts
@@ -1,20 +1,21 @@
-import os from 'node:os';
 import { GlobalConfig } from '../../../config/global';
 import * as memCache from '../memory';
 import { cache } from './decorator';
+import * as file from './file';
 import * as packageCache from '.';
 
 jest.mock('./file');
 
 describe('util/cache/package/decorator', () => {
-  const setCache = jest.spyOn(packageCache, 'set');
-
-  let count = 1;
+  const setCache = file.set;
   const getValue = jest.fn();
+  let count = 1;
 
   beforeEach(async () => {
+    jest.useRealTimers();
+    GlobalConfig.reset();
     memCache.init();
-    await packageCache.init({ cacheDir: os.tmpdir() });
+    await packageCache.init({ cacheDir: 'some-dir' });
     count = 1;
     getValue.mockImplementation(() => {
       const res = String(100 * count + 10 * count + count);
@@ -170,15 +171,10 @@ describe('util/cache/package/decorator', () => {
     }
 
     beforeEach(() => {
-      jest.useFakeTimers({ advanceTimers: false });
+      jest.useFakeTimers();
       GlobalConfig.set({ cacheHardTtlMinutes: 2 });
     });
 
-    afterEach(() => {
-      jest.useRealTimers();
-      GlobalConfig.reset();
-    });
-
     it('updates cached result', async () => {
       const obj = new Class();
 
diff --git a/lib/util/cache/repository/impl/local.spec.ts b/lib/util/cache/repository/impl/local.spec.ts
index e3f6e1f78b51d035264f99c4a23c9d89faa5fad5..e02178f2857ea65194372084688df277bec57ae5 100644
--- a/lib/util/cache/repository/impl/local.spec.ts
+++ b/lib/util/cache/repository/impl/local.spec.ts
@@ -34,7 +34,6 @@ async function createCacheRecord(
 
 describe('util/cache/repository/impl/local', () => {
   beforeEach(() => {
-    jest.resetAllMocks();
     GlobalConfig.set({ cacheDir: '/tmp/cache', platform: 'github' });
     fs.cachePathExists.mockResolvedValue(true);
   });
diff --git a/lib/util/cache/repository/index.spec.ts b/lib/util/cache/repository/index.spec.ts
index 3bfe5a9093ebefa57e4afddab2ab4e80a02df56c..b8158d58d9ce77aaa8033be77213491ce614864f 100644
--- a/lib/util/cache/repository/index.spec.ts
+++ b/lib/util/cache/repository/index.spec.ts
@@ -13,7 +13,6 @@ const fs = mocked(_fs);
 describe('util/cache/repository/index', () => {
   beforeEach(() => {
     resetCache();
-    jest.resetAllMocks();
     GlobalConfig.set({ cacheDir: '/tmp/cache', platform: 'github' });
   });
 
diff --git a/lib/util/check-token.spec.ts b/lib/util/check-token.spec.ts
index 2251342441891849a4a44e75ac1b1b0a8f16c476..67b95950c2e9cb27d7970e80ed60251f504071dd 100644
--- a/lib/util/check-token.spec.ts
+++ b/lib/util/check-token.spec.ts
@@ -1,3 +1,4 @@
+import { mockDeep } from 'jest-mock-extended';
 import { hostRules, logger } from '../../test/util';
 import { GlobalConfig } from '../config/global';
 import { GithubReleasesDatasource } from '../modules/datasource/github-releases';
@@ -13,12 +14,11 @@ import {
   takePersonalAccessTokenIfPossible,
 } from './check-token';
 
-jest.mock('./host-rules');
+jest.mock('./host-rules', () => mockDeep());
 
 describe('util/check-token', () => {
   describe('checkGithubToken', () => {
     beforeEach(() => {
-      jest.resetAllMocks();
       memCache.reset();
       GlobalConfig.set({ githubTokenWarn: true });
     });
diff --git a/lib/util/exec/docker/index.spec.ts b/lib/util/exec/docker/index.spec.ts
index 376a8a523b536f76fe35b3e23c8a81ea9815f8b9..ab3eb066a1efa85d21ea914cd9c8134c67370040 100644
--- a/lib/util/exec/docker/index.spec.ts
+++ b/lib/util/exec/docker/index.spec.ts
@@ -1,3 +1,4 @@
+import { mockDeep } from 'jest-mock-extended';
 import { mockExecAll, mockExecSequence } from '../../../../test/exec-util';
 import { partial } from '../../../../test/util';
 import { GlobalConfig } from '../../../config/global';
@@ -15,13 +16,9 @@ import {
   sideCarImage,
 } from '.';
 
-jest.mock('../../../modules/datasource');
+jest.mock('../../../modules/datasource', () => mockDeep());
 
 describe('util/exec/docker/index', () => {
-  beforeEach(() => {
-    jest.resetAllMocks();
-  });
-
   describe('prefetchDockerImage', () => {
     beforeEach(() => {
       resetPrefetchedImages();
diff --git a/lib/util/exec/index.spec.ts b/lib/util/exec/index.spec.ts
index f545e080727ba329bd7bef30d851b254ea318505..8aa42878eaca3d2eef632562fa52e3d85e5f7b95 100644
--- a/lib/util/exec/index.spec.ts
+++ b/lib/util/exec/index.spec.ts
@@ -1,3 +1,4 @@
+import { mockDeep } from 'jest-mock-extended';
 import { exec as cpExec, envMock } from '../../../test/exec-util';
 import { mockedFunction } from '../../../test/util';
 import { GlobalConfig } from '../../config/global';
@@ -11,11 +12,10 @@ import { exec } from '.';
 const getHermitEnvsMock = mockedFunction(getHermitEnvs);
 
 jest.mock('./hermit', () => ({
-  // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
-  ...(jest.requireActual('./hermit') as any),
+  ...jest.requireActual<typeof import('./hermit')>('./hermit'),
   getHermitEnvs: jest.fn(),
 }));
-jest.mock('../../modules/datasource');
+jest.mock('../../modules/datasource', () => mockDeep());
 
 interface TestInput {
   processEnv: Record<string, string>;
@@ -46,7 +46,6 @@ describe('util/exec/index', () => {
 
   beforeEach(() => {
     dockerModule.resetPrefetchedImages();
-    jest.resetAllMocks();
     jest.restoreAllMocks();
     jest.resetModules();
     processEnvOrig = process.env;
diff --git a/lib/util/git/index.spec.ts b/lib/util/git/index.spec.ts
index 8d8c38225c9db402d4b982860543eb47b213ef6e..3902d862a47c263bde6dfb215af01ffc9fab8f7d 100644
--- a/lib/util/git/index.spec.ts
+++ b/lib/util/git/index.spec.ts
@@ -892,10 +892,6 @@ describe('util/git/index', () => {
     });
 
     describe('cachedConflictResult', () => {
-      beforeEach(() => {
-        jest.resetAllMocks();
-      });
-
       it('returns cached values', async () => {
         conflictsCache.getCachedConflictResult.mockReturnValue(true);
 
diff --git a/lib/util/git/private-key.spec.ts b/lib/util/git/private-key.spec.ts
index 9ecbbe74f0b2613bd3083c99739a7cbc1c205352..667b8c585318b7095b147450dad8b8dcfc80ff65 100644
--- a/lib/util/git/private-key.spec.ts
+++ b/lib/util/git/private-key.spec.ts
@@ -1,10 +1,15 @@
-import { Fixtures } from '../../../test/fixtures';
 import { mocked } from '../../../test/util';
 import * as exec_ from '../exec';
 import { configSigningKey, writePrivateKey } from './private-key';
 import { setPrivateKey } from '.';
 
-jest.mock('fs-extra', () => Fixtures.fsExtra());
+jest.mock('fs-extra', () =>
+  jest
+    .requireActual<typeof import('../../../test/fixtures')>(
+      '../../../test/fixtures'
+    )
+    .fsExtra()
+);
 jest.mock('../exec');
 
 const exec = mocked(exec_);
diff --git a/lib/util/git/semantic.spec.ts b/lib/util/git/semantic.spec.ts
index d15876b9be88c9343b2828387b6f5500098f7945..cea1cd399bb21f6d78c40b4f336d81337bd0b556 100644
--- a/lib/util/git/semantic.spec.ts
+++ b/lib/util/git/semantic.spec.ts
@@ -7,7 +7,6 @@ jest.mock('.');
 let config: RenovateConfig;
 
 beforeEach(() => {
-  jest.resetAllMocks();
   config = partial<RenovateConfig>();
 });
 
diff --git a/lib/util/git/url.spec.ts b/lib/util/git/url.spec.ts
index ca32e45f8a1829d3c1612a65d17055ae23a3c534..194e653775f91a0c7082d49b2bbd17c99f115d20 100644
--- a/lib/util/git/url.spec.ts
+++ b/lib/util/git/url.spec.ts
@@ -1,7 +1,8 @@
+import { mockDeep } from 'jest-mock-extended';
 import { hostRules } from '../../../test/util';
 import { getHttpUrl, getRemoteUrlWithToken, parseGitUrl } from './url';
 
-jest.mock('../host-rules');
+jest.mock('../host-rules', () => mockDeep());
 
 describe('util/git/url', () => {
   describe('parseGitUrl', () => {
diff --git a/lib/util/github/graphql/cache-strategies/memory-cache-strategy.spec.ts b/lib/util/github/graphql/cache-strategies/memory-cache-strategy.spec.ts
index 88849193a12b66de745641c49f44fe0a9a7857ff..13bd58bceb29bc4958932991621e52f75eb68be8 100644
--- a/lib/util/github/graphql/cache-strategies/memory-cache-strategy.spec.ts
+++ b/lib/util/github/graphql/cache-strategies/memory-cache-strategy.spec.ts
@@ -33,7 +33,6 @@ type CacheRecord = GithubGraphqlCacheRecord<GithubDatasourceItem>;
 
 describe('util/github/graphql/cache-strategies/memory-cache-strategy', () => {
   beforeEach(() => {
-    jest.resetAllMocks();
     memCache.init();
   });
 
diff --git a/lib/util/github/graphql/datasource-fetcher.spec.ts b/lib/util/github/graphql/datasource-fetcher.spec.ts
index bed035a5643e1b068cced25050462ee860d76e01..f2c76fdb8f8707c97a10c27d5fc023cf8900d30f 100644
--- a/lib/util/github/graphql/datasource-fetcher.spec.ts
+++ b/lib/util/github/graphql/datasource-fetcher.spec.ts
@@ -108,7 +108,6 @@ describe('util/github/graphql/datasource-fetcher', () => {
     const t3 = '01-01-2023';
 
     beforeEach(() => {
-      jest.resetAllMocks();
       http = new GithubHttp();
     });
 
diff --git a/lib/util/http/bitbucket-server.spec.ts b/lib/util/http/bitbucket-server.spec.ts
index 56d331f72ce1bbc65ae18a889a33784569ba0660..238e08a4e99be58bb281ba047f2e29d4a20380a9 100644
--- a/lib/util/http/bitbucket-server.spec.ts
+++ b/lib/util/http/bitbucket-server.spec.ts
@@ -10,9 +10,6 @@ describe('util/http/bitbucket-server', () => {
   beforeEach(() => {
     api = new BitbucketServerHttp();
 
-    // reset module
-    jest.resetAllMocks();
-
     // clean up hostRules
     hostRules.clear();
     hostRules.add({
diff --git a/lib/util/http/bitbucket.spec.ts b/lib/util/http/bitbucket.spec.ts
index 16bf1956de3906b52ecbcd32ed28747ec3f0f6ea..52cc342b7d576198b8d9690e1b8b0860e40b4e66 100644
--- a/lib/util/http/bitbucket.spec.ts
+++ b/lib/util/http/bitbucket.spec.ts
@@ -11,9 +11,6 @@ describe('util/http/bitbucket', () => {
   beforeEach(() => {
     api = new BitbucketHttp();
 
-    // reset module
-    jest.resetAllMocks();
-
     // clean up hostRules
     hostRules.clear();
     hostRules.add({
diff --git a/lib/util/http/gitea.spec.ts b/lib/util/http/gitea.spec.ts
index cc7426638bb4ea190fb3d2515c4cbcd78e9f436d..3e9b7bd0e789189b2c41f67cb462b6a267318e3e 100644
--- a/lib/util/http/gitea.spec.ts
+++ b/lib/util/http/gitea.spec.ts
@@ -9,8 +9,6 @@ describe('util/http/gitea', () => {
   beforeEach(() => {
     giteaHttp = new GiteaHttp();
 
-    jest.resetAllMocks();
-
     setBaseUrl(baseUrl);
   });
 
diff --git a/lib/util/http/github.spec.ts b/lib/util/http/github.spec.ts
index fe85535129ac9321c2b7d137aed34936c3c8de91..5d66f42fba1f520073ac3a0c28f2cbc2318b0df0 100644
--- a/lib/util/http/github.spec.ts
+++ b/lib/util/http/github.spec.ts
@@ -55,7 +55,6 @@ describe('util/http/github', () => {
     delete process.env.RENOVATE_X_REBASE_PAGINATION_LINKS;
     githubApi = new GithubHttp();
     setBaseUrl(githubApiHost);
-    jest.resetAllMocks();
     repoCache = {};
     repositoryCache.getCache.mockReturnValue(repoCache);
   });
diff --git a/lib/util/http/gitlab.spec.ts b/lib/util/http/gitlab.spec.ts
index 38dbb79e45c3980ce9232f93a68488397ad8b057..7a63dd6a114795516925a12859012322c0a2f0fe 100644
--- a/lib/util/http/gitlab.spec.ts
+++ b/lib/util/http/gitlab.spec.ts
@@ -27,8 +27,6 @@ describe('util/http/gitlab', () => {
   });
 
   afterEach(() => {
-    jest.resetAllMocks();
-
     hostRules.clear();
   });
 
diff --git a/lib/util/http/host-rules.spec.ts b/lib/util/http/host-rules.spec.ts
index 6ad1f655b5a02ce5e7e2c45a1fcf2f36c95b4aa8..6b8667d70c78571b4756458c5bd9e02fb9fcb41c 100644
--- a/lib/util/http/host-rules.spec.ts
+++ b/lib/util/http/host-rules.spec.ts
@@ -14,9 +14,6 @@ describe('util/http/host-rules', () => {
   };
 
   beforeEach(() => {
-    // reset module
-    jest.resetAllMocks();
-
     delete process.env.HTTP_PROXY;
 
     // clean up hostRules
diff --git a/lib/util/http/index.spec.ts b/lib/util/http/index.spec.ts
index 49f9f1aff03ec9cfcc744c9f31a35ada6e329100..304a368c6f641c72a83d8c519465e91587502f6b 100644
--- a/lib/util/http/index.spec.ts
+++ b/lib/util/http/index.spec.ts
@@ -320,7 +320,6 @@ describe('util/http/index', () => {
       .transform(({ x, y }) => `${x} + ${y} = ${x + y}`);
 
     beforeEach(() => {
-      jest.resetAllMocks();
       memCache.init();
     });
 
diff --git a/lib/util/json-writer/editor-config.spec.ts b/lib/util/json-writer/editor-config.spec.ts
index 855844ff47f327554a450e1bcb76bec5bc6e0388..0139c907666dc52ef586ede5c9addd88773d2a0a 100644
--- a/lib/util/json-writer/editor-config.spec.ts
+++ b/lib/util/json-writer/editor-config.spec.ts
@@ -5,16 +5,18 @@ import { GlobalConfig } from '../../config/global';
 import { EditorConfig } from './editor-config';
 
 // use real fs to read wasm files for `@one-ini/wasm`
-jest.mock('fs', () => ({
-  ...memfs,
-  readFileSync: (file: string, ...args: any[]) => {
-    if (file.endsWith('.wasm')) {
-      const realFs = jest.requireActual<typeof import('fs')>('fs');
-      return realFs.readFileSync(file, ...args);
-    }
-    return memfs.readFileSync(file, ...args);
-  },
-}));
+jest.mock('fs', () => {
+  const realFs = jest.requireActual<typeof import('fs')>('fs');
+  return {
+    ...memfs,
+    readFileSync: (file: string, ...args: any[]) => {
+      if (file.endsWith('.wasm')) {
+        return realFs.readFileSync(file, ...args);
+      }
+      return memfs.readFileSync(file, ...args);
+    },
+  };
+});
 
 const defaultConfigFile = configFileNames[0];
 
@@ -26,6 +28,7 @@ describe('util/json-writer/editor-config', () => {
   });
 
   beforeEach(() => {
+    jest.restoreAllMocks();
     Fixtures.reset();
   });
 
diff --git a/lib/util/merge-confidence/index.spec.ts b/lib/util/merge-confidence/index.spec.ts
index d256fe3314c9f2559e0c94f7b954e8d6be81ae5d..2fc566b37c424bac32eb385b7bcd676ffa73837b 100644
--- a/lib/util/merge-confidence/index.spec.ts
+++ b/lib/util/merge-confidence/index.spec.ts
@@ -56,7 +56,6 @@ describe('util/merge-confidence/index', () => {
     };
 
     beforeEach(() => {
-      jest.resetAllMocks();
       process.env.RENOVATE_X_MERGE_CONFIDENCE_API_BASE_URL = apiBaseUrl;
       hostRules.add(hostRule);
       initConfig();
diff --git a/lib/util/regex.spec.ts b/lib/util/regex.spec.ts
index 3283c40ec123c96a21540866daaef40884cc0deb..6125984dc8ca20954221a6bdde0fb6d6aa9092b5 100644
--- a/lib/util/regex.spec.ts
+++ b/lib/util/regex.spec.ts
@@ -29,12 +29,12 @@ describe('util/regex', () => {
     expect(regEx(/bar/g)).not.toBe(/bar/g);
   });
 
-  it('Falls back to RegExp', () => {
+  it('Falls back to RegExp', async () => {
     jest.doMock('re2', () => {
       throw new Error();
     });
 
-    const regex = require('./regex');
+    const regex = await import('./regex');
     expect(regex.regEx('foo')).toBeInstanceOf(RegExp);
   });
 
diff --git a/lib/workers/global/autodiscover.spec.ts b/lib/workers/global/autodiscover.spec.ts
index 6566d0ac9958f8c49922d10d209493c70dd612cf..8889ec09afa0a444a8d75a6da2abe4c6ddea9006 100644
--- a/lib/workers/global/autodiscover.spec.ts
+++ b/lib/workers/global/autodiscover.spec.ts
@@ -16,7 +16,6 @@ describe('workers/global/autodiscover', () => {
   let config: RenovateConfig;
 
   beforeEach(async () => {
-    jest.resetAllMocks();
     config = {};
     await platform.initPlatform({
       platform: 'github',
diff --git a/lib/workers/global/config/parse/file.spec.ts b/lib/workers/global/config/parse/file.spec.ts
index 0a786e8f80a079978be06b5c8a8ef8dbd68e84e3..05fcc01fb88162f922f7ad81685981906834797b 100644
--- a/lib/workers/global/config/parse/file.spec.ts
+++ b/lib/workers/global/config/parse/file.spec.ts
@@ -134,7 +134,9 @@ describe('workers/global/config/parse/file', () => {
       fsRemoveSpy.mockImplementationOnce(() => {
         // no-op
       });
-      fsPathExistsSpy.mockResolvedValueOnce(true as never);
+      fsPathExistsSpy
+        .mockResolvedValueOnce(true as never)
+        .mockResolvedValueOnce(true as never);
       const configFile = upath.resolve(tmp.path, './config.json');
       fs.writeFileSync(configFile, `{"token": "abc"}`, { encoding: 'utf8' });
 
diff --git a/lib/workers/global/config/parse/index.spec.ts b/lib/workers/global/config/parse/index.spec.ts
index d7cf9ebce0650c01a0e10ee3e41a6f3230b0980e..6301ecc3f24d2660e7f701f93131e0e0f3274079 100644
--- a/lib/workers/global/config/parse/index.spec.ts
+++ b/lib/workers/global/config/parse/index.spec.ts
@@ -7,11 +7,7 @@ import * as _hostRulesFromEnv from './host-rules-from-env';
 jest.mock('../../../../modules/datasource/npm');
 jest.mock('../../../../util/fs');
 jest.mock('./host-rules-from-env');
-try {
-  jest.mock('../../config.js');
-} catch (err) {
-  // file does not exist
-}
+jest.mock('../../config.js', () => ({}), { virtual: true });
 
 const { hostRulesFromEnv } = mocked(_hostRulesFromEnv);
 
diff --git a/lib/workers/global/index.spec.ts b/lib/workers/global/index.spec.ts
index 0bc6aec1add7c0064ffa2c96d06e526f1b0565fb..f950d5b4b0536a0c1e22ebc58b7130069bab6fe2 100644
--- a/lib/workers/global/index.spec.ts
+++ b/lib/workers/global/index.spec.ts
@@ -1,4 +1,3 @@
-import { expect } from '@jest/globals';
 import { ERROR, WARN } from 'bunyan';
 import fs from 'fs-extra';
 import { logger, mocked } from '../../../test/util';
diff --git a/lib/workers/repository/config-migration/branch/commit-message.spec.ts b/lib/workers/repository/config-migration/branch/commit-message.spec.ts
index 48c7692e860483b77617bfcce3dacdba446bdef6..a2ab74b131f6e421b8c2c0acf18ac82af645db23 100644
--- a/lib/workers/repository/config-migration/branch/commit-message.spec.ts
+++ b/lib/workers/repository/config-migration/branch/commit-message.spec.ts
@@ -5,10 +5,6 @@ describe('workers/repository/config-migration/branch/commit-message', () => {
   const config = getConfig();
   const fileName = 'renovate.json';
 
-  afterAll(() => {
-    jest.resetAllMocks();
-  });
-
   it('creates semantic commit message', () => {
     config.semanticCommits = 'enabled';
     const commitMessageFactory = new ConfigMigrationCommitMessageFactory(
diff --git a/lib/workers/repository/config-migration/branch/index.spec.ts b/lib/workers/repository/config-migration/branch/index.spec.ts
index 9b1dab3e4ec6fceaf3888f0bc3934bd1633f0379..3d4754978b4ae8d4b3025d1964400777679ab93b 100644
--- a/lib/workers/repository/config-migration/branch/index.spec.ts
+++ b/lib/workers/repository/config-migration/branch/index.spec.ts
@@ -33,7 +33,6 @@ describe('workers/repository/config-migration/branch/index', () => {
       GlobalConfig.set({
         dryRun: null,
       });
-      jest.resetAllMocks();
       config = getConfig();
       config.branchPrefix = 'some/';
     });
diff --git a/lib/workers/repository/config-migration/branch/migrated-data.spec.ts b/lib/workers/repository/config-migration/branch/migrated-data.spec.ts
index db3b27b34648668c2c710fdcede2a913ac947a3b..8e892b8409206c0d8504b6b12d5da6c4eee7ed16 100644
--- a/lib/workers/repository/config-migration/branch/migrated-data.spec.ts
+++ b/lib/workers/repository/config-migration/branch/migrated-data.spec.ts
@@ -26,7 +26,6 @@ const formattedMigratedData = Fixtures.getJson(
 describe('workers/repository/config-migration/branch/migrated-data', () => {
   describe('MigratedDataFactory.getAsync', () => {
     beforeEach(() => {
-      jest.resetAllMocks();
       mockedFunction(detectIndent).mockReturnValue({
         type: 'space',
         amount: 2,
diff --git a/lib/workers/repository/config-migration/index.spec.ts b/lib/workers/repository/config-migration/index.spec.ts
index eaed898146c97a9e059e78fd01568b7e8e0685e4..9f107189397a1af0d5f2e621b2826508db72584d 100644
--- a/lib/workers/repository/config-migration/index.spec.ts
+++ b/lib/workers/repository/config-migration/index.spec.ts
@@ -21,7 +21,6 @@ const config = {
 
 describe('workers/repository/config-migration/index', () => {
   beforeEach(() => {
-    jest.resetAllMocks();
     mockedFunction(MigratedDataFactory.getAsync).mockResolvedValue({
       filename,
       content,
diff --git a/lib/workers/repository/config-migration/pr/index.spec.ts b/lib/workers/repository/config-migration/pr/index.spec.ts
index 25f4ab65f1344235f82e02629b2643039b2fc1ac..d577ac254f34686cffa2336296c5c7b4efc95cc3 100644
--- a/lib/workers/repository/config-migration/pr/index.spec.ts
+++ b/lib/workers/repository/config-migration/pr/index.spec.ts
@@ -37,7 +37,7 @@ describe('workers/repository/config-migration/pr/index', () => {
     GlobalConfig.set({
       dryRun: null,
     });
-    jest.resetAllMocks();
+
     config = {
       ...getConfig(),
       configMigration: true,
@@ -251,7 +251,6 @@ describe('workers/repository/config-migration/pr/index', () => {
     const err = partial<RequestError>({ response });
 
     beforeEach(() => {
-      jest.resetAllMocks();
       GlobalConfig.reset();
       scm.deleteBranch.mockResolvedValue();
     });
diff --git a/lib/workers/repository/configured.spec.ts b/lib/workers/repository/configured.spec.ts
index c219be9444ad7d0aa9395950f81f24ab6ce81548..c7c4113d3206102eab1f018587dda1c529645f28 100644
--- a/lib/workers/repository/configured.spec.ts
+++ b/lib/workers/repository/configured.spec.ts
@@ -4,7 +4,6 @@ import { checkIfConfigured } from './configured';
 let config: RenovateConfig;
 
 beforeEach(() => {
-  jest.resetAllMocks();
   config = partial<RenovateConfig>({
     enabled: true,
     forkProcessing: 'auto',
diff --git a/lib/workers/repository/dependency-dashboard.spec.ts b/lib/workers/repository/dependency-dashboard.spec.ts
index 0f22e3e558ea8657718530aee6f0019297122fd1..318631a68b48d2092cbcc021cd2d5337378a110c 100644
--- a/lib/workers/repository/dependency-dashboard.spec.ts
+++ b/lib/workers/repository/dependency-dashboard.spec.ts
@@ -1021,10 +1021,6 @@ describe('workers/repository/dependency-dashboard', () => {
           PackageFiles.clear();
         });
 
-        afterAll(() => {
-          jest.resetAllMocks();
-        });
-
         it('does not truncates as there is enough space to fit', () => {
           PackageFiles.add('main', packageFiles);
           const nonTruncated = PackageFiles.getDashboardMarkdown(Infinity);
diff --git a/lib/workers/repository/error-config.spec.ts b/lib/workers/repository/error-config.spec.ts
index 2eb296e73ab4a91fd6ff51aabce09129eb4c5cdf..7731fb58c206c42152395fbc7b4f235c4038f8c9 100644
--- a/lib/workers/repository/error-config.spec.ts
+++ b/lib/workers/repository/error-config.spec.ts
@@ -14,7 +14,6 @@ jest.mock('../../modules/platform');
 let config: RenovateConfig;
 
 beforeEach(() => {
-  jest.resetAllMocks();
   // default values
   config = partial<RenovateConfig>({
     onboardingBranch: 'configure/renovate',
diff --git a/lib/workers/repository/error.spec.ts b/lib/workers/repository/error.spec.ts
index 07cd0838ed650c36c869f74c294e404a6c792f9d..f643a7f5401a9eb723b0fc895c7819a342c679c7 100644
--- a/lib/workers/repository/error.spec.ts
+++ b/lib/workers/repository/error.spec.ts
@@ -36,7 +36,6 @@ jest.mock('./error-config');
 let config: RenovateConfig;
 
 beforeEach(() => {
-  jest.resetAllMocks();
   config = partial<RenovateConfig>({ branchList: [] });
 });
 
diff --git a/lib/workers/repository/errors-warnings.spec.ts b/lib/workers/repository/errors-warnings.spec.ts
index f7f1b91c7ae4801c6a31703403c109dad4efaccc..2123c920003a3bb3ff4e3b688bf362533943a2e9 100644
--- a/lib/workers/repository/errors-warnings.spec.ts
+++ b/lib/workers/repository/errors-warnings.spec.ts
@@ -13,7 +13,6 @@ describe('workers/repository/errors-warnings', () => {
     let config: RenovateConfig;
 
     beforeEach(() => {
-      jest.resetAllMocks();
       config = partial<RenovateConfig>();
     });
 
@@ -46,10 +45,6 @@ describe('workers/repository/errors-warnings', () => {
   });
 
   describe('getDepWarningsPR()', () => {
-    beforeEach(() => {
-      jest.resetAllMocks();
-    });
-
     it('returns 2 pr warnings text dependencyDashboard true', () => {
       const config: RenovateConfig = {};
       const dependencyDashboard = true;
@@ -164,10 +159,6 @@ describe('workers/repository/errors-warnings', () => {
   });
 
   describe('getDepWarningsDashboard()', () => {
-    beforeEach(() => {
-      jest.resetAllMocks();
-    });
-
     it('returns dependency dashboard warning text', () => {
       const config: RenovateConfig = {};
       const packageFiles: Record<string, PackageFile[]> = {
@@ -239,7 +230,6 @@ describe('workers/repository/errors-warnings', () => {
     let config: RenovateConfig;
 
     beforeEach(() => {
-      jest.resetAllMocks();
       config = partial<RenovateConfig>();
     });
 
diff --git a/lib/workers/repository/extract/index.spec.ts b/lib/workers/repository/extract/index.spec.ts
index 5c21ec155afcfbaa74c85950397fee4a10a3236c..7d257cbbc3a049d2669162408044f83de7355f21 100644
--- a/lib/workers/repository/extract/index.spec.ts
+++ b/lib/workers/repository/extract/index.spec.ts
@@ -17,7 +17,6 @@ describe('workers/repository/extract/index', () => {
     const fileList = ['README', 'package.json', 'tasks/ansible.yaml'];
 
     beforeEach(() => {
-      jest.resetAllMocks();
       scm.getFileList.mockResolvedValue(fileList);
       config = getConfig();
     });
diff --git a/lib/workers/repository/extract/manager-files.spec.ts b/lib/workers/repository/extract/manager-files.spec.ts
index d081eab4b9722767c8821a6fb22eba2e129749cc..8f2fa4ff5ded473419709d08507c669119fb6362 100644
--- a/lib/workers/repository/extract/manager-files.spec.ts
+++ b/lib/workers/repository/extract/manager-files.spec.ts
@@ -16,7 +16,6 @@ describe('workers/repository/extract/manager-files', () => {
     let config: RenovateConfig;
 
     beforeEach(() => {
-      jest.resetAllMocks();
       config = partial<RenovateConfig>();
     });
 
diff --git a/lib/workers/repository/finalize/prune.spec.ts b/lib/workers/repository/finalize/prune.spec.ts
index 9e0a23074c8df229d4c607179207bc6b03b1502f..cca995e99eccfe467345d5f42a564d2289ea8eb6 100644
--- a/lib/workers/repository/finalize/prune.spec.ts
+++ b/lib/workers/repository/finalize/prune.spec.ts
@@ -14,7 +14,6 @@ jest.mock('../../../util/git');
 let config: RenovateConfig;
 
 beforeEach(() => {
-  jest.resetAllMocks();
   config = partial<RenovateConfig>({
     repoIsOnboarded: true,
     branchPrefix: `renovate/`,
diff --git a/lib/workers/repository/init/apis.spec.ts b/lib/workers/repository/init/apis.spec.ts
index 8295f41bd42f9875c208a987839c7afdf97c8e0a..5359522d7183151cdc9995d2226be0a9a5703b65 100644
--- a/lib/workers/repository/init/apis.spec.ts
+++ b/lib/workers/repository/init/apis.spec.ts
@@ -19,10 +19,6 @@ describe('workers/repository/init/apis', () => {
       delete config.forkProcessing;
     });
 
-    afterEach(() => {
-      jest.resetAllMocks();
-    });
-
     it('runs', async () => {
       platform.initRepo.mockResolvedValueOnce({
         defaultBranch: 'master',
diff --git a/lib/workers/repository/init/index.spec.ts b/lib/workers/repository/init/index.spec.ts
index 7681977572d679f23b0ae91bb3ff3d98cfbcd394..4300e9231c0451f115232168b935b053d4405b56 100644
--- a/lib/workers/repository/init/index.spec.ts
+++ b/lib/workers/repository/init/index.spec.ts
@@ -14,6 +14,10 @@ jest.mock('../init/apis');
 jest.mock('../init/config');
 jest.mock('../init/merge');
 jest.mock('../../../config/secrets');
+jest.mock('../../../modules/platform', () => ({
+  platform: { initRepo: jest.fn() },
+  getPlatformList: jest.fn(),
+}));
 
 const apis = mocked(_apis);
 const config = mocked(_config);
diff --git a/lib/workers/repository/init/merge.spec.ts b/lib/workers/repository/init/merge.spec.ts
index 7fe08d29158a88cd4e79683c82cd80a14b25dc63..5a191d4e205bc4c247318c187647e924c5122454 100644
--- a/lib/workers/repository/init/merge.spec.ts
+++ b/lib/workers/repository/init/merge.spec.ts
@@ -34,7 +34,6 @@ let config: RenovateConfig;
 
 beforeEach(() => {
   memCache.init();
-  jest.resetAllMocks();
   config = getConfig();
   config.errors = [];
   config.warnings = [];
diff --git a/lib/workers/repository/init/vulnerability.spec.ts b/lib/workers/repository/init/vulnerability.spec.ts
index ee99bb3a1493f5fa1ef734e5f388544ee37c98ad..de28fe48d93698d1e66df194a8433375091898a1 100644
--- a/lib/workers/repository/init/vulnerability.spec.ts
+++ b/lib/workers/repository/init/vulnerability.spec.ts
@@ -7,7 +7,6 @@ import { detectVulnerabilityAlerts } from './vulnerability';
 let config: RenovateConfig;
 
 beforeEach(() => {
-  jest.resetAllMocks();
   config = getConfig();
 });
 
diff --git a/lib/workers/repository/onboarding/branch/index.spec.ts b/lib/workers/repository/onboarding/branch/index.spec.ts
index 9b8f248de9dfa9c82f453b0f57e1ff9e793b8ee3..aaecdb04bd56a892fa51e77aaae105feaa57207d 100644
--- a/lib/workers/repository/onboarding/branch/index.spec.ts
+++ b/lib/workers/repository/onboarding/branch/index.spec.ts
@@ -42,7 +42,6 @@ describe('workers/repository/onboarding/branch/index', () => {
 
     beforeEach(() => {
       memCache.init();
-      jest.resetAllMocks();
       config = getConfig();
       config.repository = 'some/repo';
       OnboardingState.prUpdateRequested = false;
diff --git a/lib/workers/repository/onboarding/branch/onboarding-branch-cache.spec.ts b/lib/workers/repository/onboarding/branch/onboarding-branch-cache.spec.ts
index b1e64d0a57c203f924448a85e37dc52c16594b07..aabb3d30c021cdf90332bcec953a635fa019c093 100644
--- a/lib/workers/repository/onboarding/branch/onboarding-branch-cache.spec.ts
+++ b/lib/workers/repository/onboarding/branch/onboarding-branch-cache.spec.ts
@@ -251,6 +251,7 @@ describe('workers/repository/onboarding/branch/onboarding-branch-cache', () => {
     });
 
     it('returns undefined', () => {
+      cache.getCache.mockReturnValueOnce({});
       expect(getOnboardingFileNameFromCache()).toBeUndefined();
     });
   });
@@ -267,6 +268,7 @@ describe('workers/repository/onboarding/branch/onboarding-branch-cache', () => {
     });
 
     it('returns undefined', () => {
+      cache.getCache.mockReturnValueOnce({});
       expect(getOnboardingConfigFromCache()).toBeUndefined();
     });
   });
diff --git a/lib/workers/repository/onboarding/pr/base-branch.spec.ts b/lib/workers/repository/onboarding/pr/base-branch.spec.ts
index 516884c129307161e2a816f024178c9fa41cdaad..a499bc13d62bd6f552adaee200c72856ce4f9e0b 100644
--- a/lib/workers/repository/onboarding/pr/base-branch.spec.ts
+++ b/lib/workers/repository/onboarding/pr/base-branch.spec.ts
@@ -6,7 +6,6 @@ describe('workers/repository/onboarding/pr/base-branch', () => {
     let config: RenovateConfig;
 
     beforeEach(() => {
-      jest.resetAllMocks();
       config = partial<RenovateConfig>();
     });
 
diff --git a/lib/workers/repository/onboarding/pr/config-description.spec.ts b/lib/workers/repository/onboarding/pr/config-description.spec.ts
index 538447567381c06b0d439ce19b37b17e015e52c2..c9144c5d7ee3d04f91ee2d1c7b7396d4843f1330 100644
--- a/lib/workers/repository/onboarding/pr/config-description.spec.ts
+++ b/lib/workers/repository/onboarding/pr/config-description.spec.ts
@@ -7,7 +7,6 @@ describe('workers/repository/onboarding/pr/config-description', () => {
     let config: RenovateConfig;
 
     beforeEach(() => {
-      jest.resetAllMocks();
       config = partial<RenovateConfig>();
     });
 
diff --git a/lib/workers/repository/onboarding/pr/index.spec.ts b/lib/workers/repository/onboarding/pr/index.spec.ts
index 490d9afcf26d899c916159d674e0d7b79b19bbe1..24095e9ec05ca0e43ee5acf326eda460504bcd3c 100644
--- a/lib/workers/repository/onboarding/pr/index.spec.ts
+++ b/lib/workers/repository/onboarding/pr/index.spec.ts
@@ -29,7 +29,6 @@ describe('workers/repository/onboarding/pr/index', () => {
 
     beforeEach(() => {
       memCache.init();
-      jest.resetAllMocks();
       config = {
         ...getConfig(),
         errors: [],
@@ -38,7 +37,7 @@ describe('workers/repository/onboarding/pr/index', () => {
       };
       packageFiles = { npm: [{ packageFile: 'package.json', deps: [] }] };
       branches = [];
-      platform.massageMarkdown = jest.fn((input) => input);
+      platform.massageMarkdown.mockImplementation((input) => input);
       platform.createPr.mockResolvedValueOnce(partial<Pr>());
       GlobalConfig.reset();
     });
@@ -275,9 +274,9 @@ describe('workers/repository/onboarding/pr/index', () => {
       const err = partial<RequestError>({ response });
 
       beforeEach(() => {
-        jest.resetAllMocks();
         GlobalConfig.reset();
         scm.deleteBranch.mockResolvedValue();
+        platform.createPr.mockReset();
       });
 
       it('throws when trying to create a new PR', async () => {
diff --git a/lib/workers/repository/onboarding/pr/pr-list.spec.ts b/lib/workers/repository/onboarding/pr/pr-list.spec.ts
index 9672b38b4a1a7e238e986cb3302f0397a0d1b565..b023680ec04a72266958d7804630111def431b5d 100644
--- a/lib/workers/repository/onboarding/pr/pr-list.spec.ts
+++ b/lib/workers/repository/onboarding/pr/pr-list.spec.ts
@@ -7,7 +7,6 @@ describe('workers/repository/onboarding/pr/pr-list', () => {
     let config: RenovateConfig;
 
     beforeEach(() => {
-      jest.resetAllMocks();
       config = partial<RenovateConfig>({
         prHourlyLimit: 2, // default
       });
diff --git a/lib/workers/repository/process/extract-update.spec.ts b/lib/workers/repository/process/extract-update.spec.ts
index 2dc09dccfd6def9f805a442c991c4522f71f3dc6..eadb2c2d74758c1cc80eee876b78cfb6aa1d7681 100644
--- a/lib/workers/repository/process/extract-update.spec.ts
+++ b/lib/workers/repository/process/extract-update.spec.ts
@@ -30,19 +30,21 @@ jest.mock('../../../util/git');
 const branchify = mocked(_branchify);
 const repositoryCache = mocked(_repositoryCache);
 
-branchify.branchifyUpgrades.mockResolvedValue({
-  branches: [
-    {
-      manager: 'some-manager',
-      branchName: 'some-branch',
-      baseBranch: 'base',
-      upgrades: [],
-    },
-  ],
-  branchList: ['branchName'],
-});
-
 describe('workers/repository/process/extract-update', () => {
+  beforeEach(() => {
+    branchify.branchifyUpgrades.mockResolvedValue({
+      branches: [
+        {
+          manager: 'some-manager',
+          branchName: 'some-branch',
+          baseBranch: 'base',
+          upgrades: [],
+        },
+      ],
+      branchList: ['branchName'],
+    });
+  });
+
   describe('extract()', () => {
     it('runs with no baseBranches', async () => {
       const config = {
diff --git a/lib/workers/repository/process/fetch.spec.ts b/lib/workers/repository/process/fetch.spec.ts
index 5dbda356324fc2b84f7f39059a9a63f1bb085102..d701e08868d9bbce6f4c82d7db77490130018e8c 100644
--- a/lib/workers/repository/process/fetch.spec.ts
+++ b/lib/workers/repository/process/fetch.spec.ts
@@ -15,7 +15,6 @@ describe('workers/repository/process/fetch', () => {
     let config: RenovateConfig;
 
     beforeEach(() => {
-      jest.resetAllMocks();
       config = getConfig();
     });
 
diff --git a/lib/workers/repository/process/index.spec.ts b/lib/workers/repository/process/index.spec.ts
index 807a7f68e34db56d6458e73e5e733910ecd3e677..d6cd8c148ffa800cbf8f956a2f7fa5a0ca3612a9 100644
--- a/lib/workers/repository/process/index.spec.ts
+++ b/lib/workers/repository/process/index.spec.ts
@@ -23,7 +23,6 @@ const extract = mocked(_extractUpdate).extract;
 let config: RenovateConfig;
 
 beforeEach(() => {
-  jest.resetAllMocks();
   config = getConfig();
 });
 
diff --git a/lib/workers/repository/process/limits.spec.ts b/lib/workers/repository/process/limits.spec.ts
index a3a2e19794d8c882ef1420fcbf22c28236f49380..26244f6ee8d1feca182732d508605294d49ddff9 100644
--- a/lib/workers/repository/process/limits.spec.ts
+++ b/lib/workers/repository/process/limits.spec.ts
@@ -7,7 +7,6 @@ import * as limits from './limits';
 let config: RenovateConfig;
 
 beforeEach(() => {
-  jest.resetAllMocks();
   config = partial<RenovateConfig>({
     branchPrefix: 'foo/',
     onboardingBranch: 'bar/configure',
diff --git a/lib/workers/repository/process/lookup/filter-checks.spec.ts b/lib/workers/repository/process/lookup/filter-checks.spec.ts
index 4541bfe3c760f5a9952e27a6cd16c7171ef5ac56..c07531057fc2e267b7fce2f49ab9883f5b3a2abb 100644
--- a/lib/workers/repository/process/lookup/filter-checks.spec.ts
+++ b/lib/workers/repository/process/lookup/filter-checks.spec.ts
@@ -43,7 +43,6 @@ describe('workers/repository/process/lookup/filter-checks', () => {
   beforeEach(() => {
     config = { currentVersion: '1.0.0' };
     sortedReleases = clone(releases);
-    jest.resetAllMocks();
     dateUtil.getElapsedMs.mockReturnValueOnce(toMs('3 days') ?? 0);
     dateUtil.getElapsedMs.mockReturnValueOnce(toMs('5 days') ?? 0);
     dateUtil.getElapsedMs.mockReturnValueOnce(toMs('7 days') ?? 0);
diff --git a/lib/workers/repository/process/lookup/index.spec.ts b/lib/workers/repository/process/lookup/index.spec.ts
index 2dfd3bbe0773fbffa08a10d82bd08ad0dde02f0e..a79a33241a0c2387f5ade33513b14ff7c954bfd4 100644
--- a/lib/workers/repository/process/lookup/index.spec.ts
+++ b/lib/workers/repository/process/lookup/index.spec.ts
@@ -58,8 +58,6 @@ describe('workers/repository/process/lookup/index', () => {
   const getDockerDigest = jest.spyOn(DockerDatasource.prototype, 'getDigest');
 
   beforeEach(() => {
-    // TODO: fix wrong tests
-    jest.resetAllMocks();
     // TODO: fix types #22198
     config = partial<LookupUpdateConfig>(getConfig() as never);
     config.manager = 'npm';
diff --git a/lib/workers/repository/process/write.spec.ts b/lib/workers/repository/process/write.spec.ts
index 63ef3419bbef07f40b4f3006f9d351b34b344359..421cfbac554b192fe3d35a8536c35a92b39bfcb1 100644
--- a/lib/workers/repository/process/write.spec.ts
+++ b/lib/workers/repository/process/write.spec.ts
@@ -42,7 +42,6 @@ limits.getBranchesRemaining = jest.fn().mockResolvedValue(99);
 let config: RenovateConfig;
 
 beforeEach(() => {
-  jest.resetAllMocks();
   config = getConfig();
   repoCache.getCache.mockReturnValue({});
 });
diff --git a/lib/workers/repository/result.spec.ts b/lib/workers/repository/result.spec.ts
index aced77a3d8a4af6bb4015681d16a256486776eaf..99b648d0b414a546ddfc3387ad608135483f48c6 100644
--- a/lib/workers/repository/result.spec.ts
+++ b/lib/workers/repository/result.spec.ts
@@ -4,7 +4,6 @@ import { processResult } from './result';
 let config: RenovateConfig;
 
 beforeEach(() => {
-  jest.resetAllMocks();
   config = partial<RenovateConfig>({
     repoIsActivated: true,
     repoIsOnboarded: true,
diff --git a/lib/workers/repository/update/branch/artifacts.spec.ts b/lib/workers/repository/update/branch/artifacts.spec.ts
index 1744205fbcfbf56f4745162729b3f4628c81a797..dd0a3215580f40e7a5dcc85d17a0425724d44c2a 100644
--- a/lib/workers/repository/update/branch/artifacts.spec.ts
+++ b/lib/workers/repository/update/branch/artifacts.spec.ts
@@ -8,7 +8,6 @@ describe('workers/repository/update/branch/artifacts', () => {
 
   beforeEach(() => {
     GlobalConfig.set({});
-    jest.resetAllMocks();
     config = {
       baseBranch: 'base-branch',
       manager: 'some-manager',
diff --git a/lib/workers/repository/update/branch/auto-replace.spec.ts b/lib/workers/repository/update/branch/auto-replace.spec.ts
index 1ca2bbe6d9a0ef93e6a0bc3be8087e200e95969a..3a6a1f6cf5780cc9f4d3a747d3b4e9847e77a06c 100644
--- a/lib/workers/repository/update/branch/auto-replace.spec.ts
+++ b/lib/workers/repository/update/branch/auto-replace.spec.ts
@@ -12,7 +12,7 @@ const sampleHtml = Fixtures.get(
   `../../../../modules/manager/html`
 );
 
-jest.mock('fs-extra', () => Fixtures.fsExtra());
+jest.mock('../../../../util/fs');
 
 describe('workers/repository/update/branch/auto-replace', () => {
   describe('doAutoReplace', () => {
diff --git a/lib/workers/repository/update/branch/automerge.spec.ts b/lib/workers/repository/update/branch/automerge.spec.ts
index 3abe8d0dd5a74e8e6b04309f40578158f35246ca..cc016d26471a8ddefc946cecce7e212233614a7e 100644
--- a/lib/workers/repository/update/branch/automerge.spec.ts
+++ b/lib/workers/repository/update/branch/automerge.spec.ts
@@ -15,6 +15,7 @@ describe('workers/repository/update/branch/automerge', () => {
     beforeEach(() => {
       config = partial<RenovateConfig>();
       GlobalConfig.reset();
+      isScheduledSpy.mockReturnValue(true);
     });
 
     it('returns false if not configured for automerge', async () => {
diff --git a/lib/workers/repository/update/branch/check-existing.spec.ts b/lib/workers/repository/update/branch/check-existing.spec.ts
index a26f611cbca2585f911751aa1e888ba5d2a63634..15f347deb8a46b32ca6947704fa026652d234926 100644
--- a/lib/workers/repository/update/branch/check-existing.spec.ts
+++ b/lib/workers/repository/update/branch/check-existing.spec.ts
@@ -16,7 +16,6 @@ describe('workers/repository/update/branch/check-existing', () => {
         branchName: 'some-branch',
         prTitle: 'some-title',
       } satisfies BranchConfig;
-      jest.resetAllMocks();
     });
 
     it('returns false if recreating closed PRs', async () => {
diff --git a/lib/workers/repository/update/branch/commit.spec.ts b/lib/workers/repository/update/branch/commit.spec.ts
index f98f3b57f7d842befec74d6c4dd17b94a6dd9a86..df5457426e15f0ce5956942b7f4e0cc0410715f2 100644
--- a/lib/workers/repository/update/branch/commit.spec.ts
+++ b/lib/workers/repository/update/branch/commit.spec.ts
@@ -20,7 +20,6 @@ describe('workers/repository/update/branch/commit', () => {
         updatedArtifacts: [],
         upgrades: [],
       } satisfies BranchConfig;
-      jest.resetAllMocks();
       scm.commitAndPush.mockResolvedValueOnce('123test');
       GlobalConfig.reset();
     });
diff --git a/lib/workers/repository/update/branch/index.spec.ts b/lib/workers/repository/update/branch/index.spec.ts
index b369aaa1ce77f9c5a966c763895ae4789f7f4c09..3a07c835ff92c8508542feaf631f8bb59efb9cc1 100644
--- a/lib/workers/repository/update/branch/index.spec.ts
+++ b/lib/workers/repository/update/branch/index.spec.ts
@@ -139,7 +139,6 @@ describe('workers/repository/update/branch/index', () => {
       platform.ensureComment.mockClear();
       platform.ensureCommentRemoval.mockClear();
       commit.commitFilesToBranch.mockClear();
-      jest.resetAllMocks();
       GlobalConfig.reset();
     });
 
diff --git a/lib/workers/repository/update/branch/lock-files/index.spec.ts b/lib/workers/repository/update/branch/lock-files/index.spec.ts
index e3d77a7e11202202153432c0548b73f75f1daa25..a5c3ea93a1b3263df7da52a053b11c3b674236fb 100644
--- a/lib/workers/repository/update/branch/lock-files/index.spec.ts
+++ b/lib/workers/repository/update/branch/lock-files/index.spec.ts
@@ -27,7 +27,6 @@ const { writeUpdatedPackageFiles, getAdditionalFiles } = lockFiles;
 describe('workers/repository/update/branch/lock-files/index', () => {
   describe('writeUpdatedPackageFiles', () => {
     beforeEach(() => {
-      jest.resetAllMocks();
       GlobalConfig.set({
         localDir: 'some-tmp-dir',
       });
@@ -94,10 +93,6 @@ describe('workers/repository/update/branch/lock-files/index', () => {
       jest.spyOn(lockFiles, 'determineLockFileDirs');
     });
 
-    afterEach(() => {
-      jest.resetAllMocks();
-    });
-
     it('returns no error and empty lockfiles if updateLockFiles false', async () => {
       config.updateLockFiles = false;
       const res = await getAdditionalFiles(config, { npm: [{}] });
diff --git a/lib/workers/repository/update/branch/reuse.spec.ts b/lib/workers/repository/update/branch/reuse.spec.ts
index 48363129adc0c6df930fc92e9225dd22d5e48e41..6250352edd3d6cb26318c7744c4c7604d914a107 100644
--- a/lib/workers/repository/update/branch/reuse.spec.ts
+++ b/lib/workers/repository/update/branch/reuse.spec.ts
@@ -22,7 +22,6 @@ describe('workers/repository/update/branch/reuse', () => {
         rebaseWhen: 'behind-base-branch',
         upgrades: [],
       };
-      jest.resetAllMocks();
     });
 
     it('returns false if branch does not exist', async () => {
diff --git a/lib/workers/repository/update/branch/schedule.spec.ts b/lib/workers/repository/update/branch/schedule.spec.ts
index c7ab2bb6de45755f19003c034cb697a743c66027..5b39e3729d2f27c4b0db86cf751c30a208431325 100644
--- a/lib/workers/repository/update/branch/schedule.spec.ts
+++ b/lib/workers/repository/update/branch/schedule.spec.ts
@@ -13,10 +13,6 @@ describe('workers/repository/update/branch/schedule', () => {
   });
 
   describe('hasValidSchedule(schedule)', () => {
-    beforeEach(() => {
-      jest.resetAllMocks();
-    });
-
     it('returns true for null', () => {
       expect(schedule.hasValidSchedule(null)[0]).toBeTrue();
     });
@@ -146,7 +142,7 @@ describe('workers/repository/update/branch/schedule', () => {
 
     beforeEach(() => {
       jest.setSystemTime(new Date('2017-06-30T10:50:00.000')); // Locally 2017-06-30 10:50am
-      jest.resetAllMocks();
+
       config = {};
     });
 
diff --git a/lib/workers/repository/update/branch/status-checks.spec.ts b/lib/workers/repository/update/branch/status-checks.spec.ts
index 4faeefe9c0e849cb1c6177d1f0168db38339455d..05dc5740d4a4a937fb4808c677425d1405f5cc5a 100644
--- a/lib/workers/repository/update/branch/status-checks.spec.ts
+++ b/lib/workers/repository/update/branch/status-checks.spec.ts
@@ -17,9 +17,7 @@ describe('workers/repository/update/branch/status-checks', () => {
       });
     });
 
-    afterEach(() => {
-      jest.resetAllMocks();
-    });
+    afterEach(() => {});
 
     it('returns if not configured', async () => {
       await setStability(config);
@@ -58,10 +56,6 @@ describe('workers/repository/update/branch/status-checks', () => {
       };
     });
 
-    afterEach(() => {
-      jest.resetAllMocks();
-    });
-
     it('returns if not configured', async () => {
       await setConfidence(config);
       expect(platform.getBranchStatusCheck).toHaveBeenCalledTimes(0);
diff --git a/lib/workers/repository/update/pr/automerge.spec.ts b/lib/workers/repository/update/pr/automerge.spec.ts
index b602de45160ef36113211ffae54cc1d43eaa2a88..71d389ad12681690fd8b65def26c2aabeca29c6c 100644
--- a/lib/workers/repository/update/pr/automerge.spec.ts
+++ b/lib/workers/repository/update/pr/automerge.spec.ts
@@ -19,6 +19,7 @@ describe('workers/repository/update/pr/automerge', () => {
         upgrades: [],
       } satisfies BranchConfig;
       pr = partial<Pr>();
+      spy.mockReturnValue(true);
     });
 
     it('should not automerge if not configured', async () => {
diff --git a/lib/workers/repository/update/pr/body/changelogs.spec.ts b/lib/workers/repository/update/pr/body/changelogs.spec.ts
index 44c6134a3644ab586b736addab67d970ece0e305..bcdb38ebab89ec9fe8137c2b8010b6ea9410fe3a 100644
--- a/lib/workers/repository/update/pr/body/changelogs.spec.ts
+++ b/lib/workers/repository/update/pr/body/changelogs.spec.ts
@@ -6,10 +6,6 @@ jest.mock('../../../../../util/template');
 const template = mocked(_template);
 
 describe('workers/repository/update/pr/body/changelogs', () => {
-  beforeEach(() => {
-    jest.resetAllMocks();
-  });
-
   it('returns empty string when there is no release notes', () => {
     const res = getChangelogs({
       manager: 'some-manager',
diff --git a/lib/workers/repository/update/pr/body/config-description.spec.ts b/lib/workers/repository/update/pr/body/config-description.spec.ts
index 37bba58b2cc95b504ea798da3f5af9fefb50da52..4f86453848dd44119f72120554421f8a8da7bbde 100644
--- a/lib/workers/repository/update/pr/body/config-description.spec.ts
+++ b/lib/workers/repository/update/pr/body/config-description.spec.ts
@@ -10,10 +10,6 @@ describe('workers/repository/update/pr/body/config-description', () => {
       upgrades: [],
     };
 
-    beforeEach(() => {
-      jest.resetAllMocks();
-    });
-
     it('renders stopUpdating=true', () => {
       const res = getPrConfigDescription({
         ...config,
diff --git a/lib/workers/repository/update/pr/body/footer.spec.ts b/lib/workers/repository/update/pr/body/footer.spec.ts
index d95228c3e39f26e4f88ec27c4b67eca17f75868b..3b8e8de4227f85af7ac2e02b24bc386b4a971466 100644
--- a/lib/workers/repository/update/pr/body/footer.spec.ts
+++ b/lib/workers/repository/update/pr/body/footer.spec.ts
@@ -6,10 +6,6 @@ jest.mock('../../../../../util/template');
 const template = mocked(_template);
 
 describe('workers/repository/update/pr/body/footer', () => {
-  beforeEach(() => {
-    jest.resetAllMocks();
-  });
-
   it('renders empty footer', () => {
     expect(
       getPrFooter({
diff --git a/lib/workers/repository/update/pr/body/header.spec.ts b/lib/workers/repository/update/pr/body/header.spec.ts
index c032ebe8d3f484c789bf2fb3fa4209a60b3c338c..4618598e958eb2fd65a9fe6635c705e077ae0916 100644
--- a/lib/workers/repository/update/pr/body/header.spec.ts
+++ b/lib/workers/repository/update/pr/body/header.spec.ts
@@ -6,10 +6,6 @@ jest.mock('../../../../../util/template');
 const template = mocked(_template);
 
 describe('workers/repository/update/pr/body/header', () => {
-  beforeEach(() => {
-    jest.resetAllMocks();
-  });
-
   it('renders empty header', () => {
     expect(
       getPrHeader({
diff --git a/lib/workers/repository/update/pr/body/notes.spec.ts b/lib/workers/repository/update/pr/body/notes.spec.ts
index 7141511fb79da800d4b0544f73c5fc2c83e89358..730f9788a204330274ed7846be6960db31e030a9 100644
--- a/lib/workers/repository/update/pr/body/notes.spec.ts
+++ b/lib/workers/repository/update/pr/body/notes.spec.ts
@@ -6,10 +6,6 @@ jest.mock('../../../../../util/template');
 const template = mocked(_template);
 
 describe('workers/repository/update/pr/body/notes', () => {
-  beforeEach(() => {
-    jest.resetAllMocks();
-  });
-
   it('renders notes', () => {
     template.compile.mockImplementation((x) => x);
     const res = getPrNotes({
diff --git a/lib/workers/repository/update/pr/changelog/github/index.spec.ts b/lib/workers/repository/update/pr/changelog/github/index.spec.ts
index 386e792d1b6af2f84c5f8b1fcbe63052cc139df9..57d01aa95302f1461ad7c1c8724ce9bc3605cdda 100644
--- a/lib/workers/repository/update/pr/changelog/github/index.spec.ts
+++ b/lib/workers/repository/update/pr/changelog/github/index.spec.ts
@@ -37,7 +37,6 @@ describe('workers/repository/update/pr/changelog/github/index', () => {
   afterEach(() => {
     // FIXME: add missing http mocks
     httpMock.clear(false);
-    jest.resetAllMocks();
   });
 
   describe('getChangeLogJSON', () => {
diff --git a/lib/workers/repository/update/pr/changelog/release-notes.spec.ts b/lib/workers/repository/update/pr/changelog/release-notes.spec.ts
index 9d288ee72c5af08250f042a9f8301010ea8a42c2..dda0633eb8ae08a25ec9ad9634b1c28552053ce2 100644
--- a/lib/workers/repository/update/pr/changelog/release-notes.spec.ts
+++ b/lib/workers/repository/update/pr/changelog/release-notes.spec.ts
@@ -1,3 +1,4 @@
+import { mockDeep } from 'jest-mock-extended';
 import { DateTime } from 'luxon';
 import { Fixtures } from '../../../../../../test/fixtures';
 import * as httpMock from '../../../../../../test/http-mock';
@@ -23,7 +24,7 @@ import type {
   ChangeLogResult,
 } from './types';
 
-jest.mock('../../../../../util/host-rules');
+jest.mock('../../../../../util/host-rules', () => mockDeep());
 
 const hostRules = mocked(_hostRules);
 
diff --git a/lib/workers/repository/update/pr/code-owners.spec.ts b/lib/workers/repository/update/pr/code-owners.spec.ts
index 9b57c3fa17c87ad51ab205a9c3564e452ec6e720..2b110cee785fc42d260ffc4b0ceea55a0637300b 100644
--- a/lib/workers/repository/update/pr/code-owners.spec.ts
+++ b/lib/workers/repository/update/pr/code-owners.spec.ts
@@ -12,7 +12,6 @@ describe('workers/repository/update/pr/code-owners', () => {
     let pr: Pr;
 
     beforeEach(() => {
-      jest.resetAllMocks();
       pr = mock<Pr>();
     });
 
diff --git a/lib/workers/repository/update/pr/index.spec.ts b/lib/workers/repository/update/pr/index.spec.ts
index 7a6e86eda21ac73999786d5fa8684fa0b32af5d7..6a4411f2fa521fa570374d729e3d9c39325190c8 100644
--- a/lib/workers/repository/update/pr/index.spec.ts
+++ b/lib/workers/repository/update/pr/index.spec.ts
@@ -77,7 +77,6 @@ describe('workers/repository/update/pr/index', () => {
     };
 
     beforeEach(() => {
-      jest.resetAllMocks();
       GlobalConfig.reset();
       prBody.getPrBody.mockReturnValue(body);
     });
diff --git a/lib/workers/repository/update/pr/participants.spec.ts b/lib/workers/repository/update/pr/participants.spec.ts
index 723b509588f1621bf052967ee803d05a8b85283d..699da1190fe2b1f2ecb54bb1f92e360e0fca893a 100644
--- a/lib/workers/repository/update/pr/participants.spec.ts
+++ b/lib/workers/repository/update/pr/participants.spec.ts
@@ -25,7 +25,6 @@ describe('workers/repository/update/pr/participants', () => {
 
   beforeEach(() => {
     GlobalConfig.reset();
-    jest.resetAllMocks();
   });
 
   describe('assignees', () => {
diff --git a/lib/workers/repository/updates/branchify.spec.ts b/lib/workers/repository/updates/branchify.spec.ts
index 99c0d262bb49904c178ba40603d775e550e32c15..a190b65f178e175b3089c0788d8e5491bc598d91 100644
--- a/lib/workers/repository/updates/branchify.spec.ts
+++ b/lib/workers/repository/updates/branchify.spec.ts
@@ -13,7 +13,6 @@ jest.mock('../changelog');
 let config: RenovateConfig;
 
 beforeEach(() => {
-  jest.resetAllMocks();
   config = getConfig();
   config.errors = [];
   config.warnings = [];
diff --git a/lib/workers/repository/updates/flatten.spec.ts b/lib/workers/repository/updates/flatten.spec.ts
index 1719437685e7b3c52b56fd894c3ce5db4fc3ea68..2be37367e4396fd566ecfc8c4ed31f2651417cb1 100644
--- a/lib/workers/repository/updates/flatten.spec.ts
+++ b/lib/workers/repository/updates/flatten.spec.ts
@@ -8,7 +8,6 @@ jest.mock('../../../util/git/semantic');
 let config: RenovateConfig;
 
 beforeEach(() => {
-  jest.resetAllMocks();
   config = getConfig();
   config.errors = [];
   config.warnings = [];
diff --git a/lib/workers/repository/updates/generate.spec.ts b/lib/workers/repository/updates/generate.spec.ts
index 359fc85ce4ea1bdcf2214037f45c47fb08a5cdeb..d47c2eb6070cd2348c8ddcdbc3b928a95fb7801b 100644
--- a/lib/workers/repository/updates/generate.spec.ts
+++ b/lib/workers/repository/updates/generate.spec.ts
@@ -15,7 +15,6 @@ const {
 let requiredDefaultOptions = {};
 
 beforeEach(() => {
-  jest.resetAllMocks();
   requiredDefaultOptions = {
     commitMessage,
     commitMessagePrefix,
diff --git a/test/fixtures.ts b/test/fixtures.ts
index a63fe8c415e98e2061af106a2b3d487177cc3b1e..baa9aefe44b653d3e2474502ce5825a3aaca836c 100644
--- a/test/fixtures.ts
+++ b/test/fixtures.ts
@@ -1,13 +1,11 @@
 import fs from 'node:fs';
 import type { PathLike, Stats } from 'node:fs';
-import { jest } from '@jest/globals';
 import callsite from 'callsite';
 import { DirectoryJSON, fs as memfs, vol } from 'memfs';
 import type { TDataOut } from 'memfs/lib/encoding';
 import upath from 'upath';
 
-// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
-const realFs = jest.requireActual('fs') as typeof fs;
+const realFs = fs; //jest.requireActual<typeof fs>('fs');
 
 /**
  * Class to work with in-memory file-system
@@ -86,19 +84,12 @@ export class Fixtures {
    */
   static reset(): void {
     vol.reset();
-  }
-
-  // Temporary solution, when all tests will be rewritten to Fixtures mocks can be moved into __mocks__ folder
-  static fsExtra(): any {
-    return {
-      ...memfs,
-      pathExists: jest.fn(pathExists),
-      remove: jest.fn(memfs.promises.rm),
-      readFile: jest.fn(readFile),
-      writeFile: jest.fn(memfs.promises.writeFile),
-      outputFile: jest.fn(outputFile),
-      stat: jest.fn(stat),
-    };
+    fsExtraMock.pathExists.mockImplementation(pathExists);
+    fsExtraMock.remove.mockImplementation(memfs.promises.rm);
+    fsExtraMock.readFile.mockImplementation(readFile);
+    fsExtraMock.writeFile.mockImplementation(memfs.promises.writeFile);
+    fsExtraMock.outputFile.mockImplementation(outputFile);
+    fsExtraMock.stat.mockImplementation(stat);
   }
 
   private static getPathToFixtures(fixturesRoot = '.'): string {
@@ -108,6 +99,23 @@ export class Fixtures {
   }
 }
 
+const fsExtraMock = {
+  pathExists: jest.fn(),
+  remove: jest.fn(),
+  readFile: jest.fn(),
+  writeFile: jest.fn(),
+  outputFile: jest.fn(),
+  stat: jest.fn(),
+};
+
+// Temporary solution, when all tests will be rewritten to Fixtures mocks can be moved into __mocks__ folder
+export function fsExtra(): any {
+  return {
+    ...memfs,
+    ...fsExtraMock,
+  };
+}
+
 export function readFile(fileName: string, options: any): Promise<TDataOut> {
   if (fileName.endsWith('.wasm') || fileName.endsWith('.wasm.gz')) {
     return fs.promises.readFile(fileName, options);
diff --git a/test/setup.ts b/test/setup.ts
index 4d9ccd34d51f696e858d44630c41f5448f37a390..4ee0a3ca978f261b674fa56b2f1f2779f9718452 100644
--- a/test/setup.ts
+++ b/test/setup.ts
@@ -1,173 +1,16 @@
-import type { Jest } from '@jest/environment';
 // Check for missing or pending http mocks
 import './http-mock';
-import type { Global } from '@jest/types';
-import type { AsymmetricMatchers, BaseExpect, Matchers } from 'expect';
-import type {
-  ClassLike,
-  FunctionLike,
-  MockInstance as JestMockInstance,
-  Mocked as JestMocked,
-  MockedClass as JestMockedClass,
-  MockedFunction as JestMockedFunction,
-  MockedObject as JestMockedObject,
-  SpyInstance as JestSpyInstance,
-} from 'jest-mock';
 import { mockDeep } from 'jest-mock-extended';
-import type { SnapshotMatchers } from 'jest-snapshot';
-import type { Plugin } from 'pretty-format';
-import type { PlatformScm } from '../lib/modules/platform';
+import type { Platform, PlatformScm } from '../lib/modules/platform';
 
 jest.mock('../lib/modules/platform', () => ({
-  platform: jest.createMockFromModule('../lib/modules/platform/github'),
+  platform: mockDeep<Platform>(),
   initPlatform: jest.fn(),
   getPlatformList: jest.fn(),
 }));
+
 jest.mock('../lib/modules/platform/scm', () => ({
   scm: mockDeep<PlatformScm>(),
 }));
 
-jest.mock('../lib/logger', () => jest.createMockFromModule('../lib/logger'));
-
-//------------------------------------------------
-// Required global jest types
-//------------------------------------------------
-declare global {
-  // Extension point for jest matchers
-  type JestMatchers<R, T = any> = jest.Matchers<R> &
-    SnapshotMatchers<R extends void | Promise<void> ? R : void, T> &
-    Omit<
-      Matchers<R extends void | Promise<void> ? R : void>,
-      'toMatchObject'
-    > & {
-      // TODO: override, because type issues (#22198)
-      /**
-       * Used to check that a JavaScript object matches a subset of the properties of an object
-       *
-       * Optionally, you can provide an object to use as Generic type for the expected value.
-       * This ensures that the matching object matches the structure of the provided object-like type.
-       *
-       * @example
-       *
-       * type House = {
-       *   bath: boolean;
-       *   bedrooms: number;
-       *   kitchen: {
-       *     amenities: string[];
-       *     area: number;
-       *     wallColor: string;
-       *   }
-       * };
-       *
-       * expect(desiredHouse).toMatchObject<House>({...standardHouse, kitchen: {area: 20}}) // wherein standardHouse is some base object of type House
-       */
-      toMatchObject<E extends object | any[]>(
-        expected: E
-      ): R extends void | Promise<void> ? R : void;
-    };
-}
-
-type JestInverse<Matchers> = {
-  /**
-   * Inverse next matcher. If you know how to test something, `.not` lets you test its opposite.
-   */
-  not: Matchers;
-};
-
-type JestPromiseMatchers<T> = {
-  /**
-   * Unwraps the reason of a rejected promise so any other matcher can be chained.
-   * If the promise is fulfilled the assertion fails.
-   */
-  rejects: JestMatchers<Promise<void>, T> &
-    JestInverse<JestMatchers<Promise<void>, T>>;
-  /**
-   * Unwraps the value of a fulfilled promise so any other matcher can be chained.
-   * If the promise is rejected the assertion fails.
-   */
-  resolves: JestMatchers<Promise<void>, T> &
-    JestInverse<JestMatchers<Promise<void>, T>>;
-};
-
-type JestExpect = {
-  <T = unknown>(actual: T): JestMatchers<void, T> &
-    JestInverse<JestMatchers<void, T>> &
-    JestPromiseMatchers<T>;
-  addSnapshotSerializer: (arg: Plugin) => void;
-} & BaseExpect &
-  AsymmetricMatchers &
-  JestInverse<Omit<AsymmetricMatchers, 'any' | 'anything'>> &
-  jest.Expect;
-
-type JestItEach = Global.It['each'];
-
-interface JestEach extends JestItEach {
-  (strings: TemplateStringsArray, ...placeholders: any[]): (
-    name: string,
-    fn: (arg: any) => ReturnType<Global.TestFn>,
-    timeout?: number
-  ) => void;
-}
-
-interface JestIt extends Global.It {
-  // TODO: override, because type issues (#22198)
-  each: JestEach;
-}
-
-declare global {
-  const afterAll: Global.HookBase;
-  const afterEach: Global.HookBase;
-  const beforeAll: Global.HookBase;
-  const beforeEach: Global.HookBase;
-  const describe: Global.Describe;
-  const expect: JestExpect;
-  const it: JestIt;
-  const jest: Omit<Jest, 'fn'> & {
-    // TODO: override, because type issues (#22198)
-    fn(): jest.Mock;
-    fn<T, Y extends any[]>(implementation?: (...args: Y) => T): jest.Mock<T, Y>;
-  };
-  const test: JestIt;
-
-  // eslint-disable-next-line @typescript-eslint/no-namespace
-  namespace jest {
-    /**
-     * Wraps a class, function or object type with Jest mock type definitions.
-     */
-    type Mocked<T extends object> = JestMocked<T>;
-    /**
-     * Wraps a class type with Jest mock type definitions.
-     */
-    type MockedClass<T extends ClassLike> = JestMockedClass<T>;
-    /**
-     * Wraps a function type with Jest mock type definitions.
-     */
-    type MockedFunction<T extends FunctionLike> = JestMockedFunction<T>;
-    /**
-     * Wraps an object type with Jest mock type definitions.
-     */
-    type MockedObject<T extends object> = JestMockedObject<T>;
-
-    type MockInstance<T, Y extends any[]> = JestMockInstance<(...args: Y) => T>;
-
-    interface Mock<T = any, Y extends any[] = any>
-      extends Function, // eslint-disable-line @typescript-eslint/ban-types
-        MockInstance<T, Y> {
-      new (...args: Y): T;
-      (...args: Y): T;
-    }
-
-    interface CustomMatcherResult {
-      pass: boolean;
-      message: string | (() => string);
-    }
-
-    type SpyInstance<T, Y extends any[]> = JestSpyInstance<(...args: Y) => T>;
-
-    // Extension point for jest matchers
-    interface Expect {}
-    // Extension point for jest matchers
-    // eslint-disable-next-line @typescript-eslint/no-unused-vars
-    interface Matchers<R> {}
-  }
-}
+jest.mock('../lib/logger', () => mockDeep());
diff --git a/test/types/jest.d.ts b/test/types/jest.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..9a6df8a04805e707f516a340ee4dea0e7855ead1
--- /dev/null
+++ b/test/types/jest.d.ts
@@ -0,0 +1,156 @@
+import type { AsymmetricMatchers, BaseExpect, Matchers } from 'expect';
+import type { SnapshotMatchers } from 'jest-snapshot';
+import type { Global } from '@jest/types';
+import type { Jest } from '@jest/environment';
+import type {
+  ClassLike,
+  FunctionLike,
+  MockInstance as JestMockInstance,
+  Mocked as JestMocked,
+  MockedClass as JestMockedClass,
+  MockedFunction as JestMockedFunction,
+  MockedObject as JestMockedObject,
+  SpyInstance as JestSpyInstance,
+} from 'jest-mock';
+
+//------------------------------------------------
+// Required global jest types
+//------------------------------------------------
+declare global {
+  // Extension point for jest matchers
+  type JestMatchers<R, T = any> = jest.Matchers<R> &
+    SnapshotMatchers<R extends void | Promise<void> ? R : void, T> &
+    Omit<
+      Matchers<R extends void | Promise<void> ? R : void>,
+      'toMatchObject'
+    > & {
+      // TODO: override, because type issues (#22198)
+      /**
+       * Used to check that a JavaScript object matches a subset of the properties of an object
+       *
+       * Optionally, you can provide an object to use as Generic type for the expected value.
+       * This ensures that the matching object matches the structure of the provided object-like type.
+       *
+       * @example
+       *
+       * type House = {
+       *   bath: boolean;
+       *   bedrooms: number;
+       *   kitchen: {
+       *     amenities: string[];
+       *     area: number;
+       *     wallColor: string;
+       *   }
+       * };
+       *
+       * expect(desiredHouse).toMatchObject<House>({...standardHouse, kitchen: {area: 20}}) // wherein standardHouse is some base object of type House
+       */
+      toMatchObject<E extends object | any[]>(
+        expected: E
+      ): R extends void | Promise<void> ? R : void;
+    };
+}
+
+type JestInverse<Matchers> = {
+  /**
+   * Inverse next matcher. If you know how to test something, `.not` lets you test its opposite.
+   */
+  not: Matchers;
+};
+
+type JestPromiseMatchers<T> = {
+  /**
+   * Unwraps the reason of a rejected promise so any other matcher can be chained.
+   * If the promise is fulfilled the assertion fails.
+   */
+  rejects: JestMatchers<Promise<void>, T> &
+    JestInverse<JestMatchers<Promise<void>, T>>;
+  /**
+   * Unwraps the value of a fulfilled promise so any other matcher can be chained.
+   * If the promise is rejected the assertion fails.
+   */
+  resolves: JestMatchers<Promise<void>, T> &
+    JestInverse<JestMatchers<Promise<void>, T>>;
+};
+
+type JestExpect = {
+  <T = unknown>(actual: T): JestMatchers<void, T> &
+    JestInverse<JestMatchers<void, T>> &
+    JestPromiseMatchers<T>;
+  addSnapshotSerializer: (arg: Plugin) => void;
+} & BaseExpect &
+  AsymmetricMatchers &
+  JestInverse<Omit<AsymmetricMatchers, 'any' | 'anything'>> &
+  jest.Expect;
+
+type JestItEach = Global.It['each'];
+
+interface JestEach extends JestItEach {
+  (strings: TemplateStringsArray, ...placeholders: any[]): (
+    name: string,
+    fn: (arg: any) => ReturnType<Global.TestFn>,
+    timeout?: number
+  ) => void;
+}
+
+interface JestIt extends Global.It {
+  // TODO: override, because type issues (#22198)
+  each: JestEach;
+}
+
+declare global {
+  const afterAll: Global.HookBase;
+  const afterEach: Global.HookBase;
+  const beforeAll: Global.HookBase;
+  const beforeEach: Global.HookBase;
+  const describe: Global.Describe;
+  const expect: JestExpect;
+  const it: JestIt;
+  var jest: Omit<Jest, 'fn'> & {
+    // TODO: override, because type issues (#22198)
+    fn(): jest.Mock;
+    fn<T, Y extends any[]>(implementation?: (...args: Y) => T): jest.Mock<T, Y>;
+  };
+  const test: JestIt;
+
+  namespace jest {
+    /**
+     * Wraps a class, function or object type with Jest mock type definitions.
+     */
+    type Mocked<T extends object> = JestMocked<T>;
+    /**
+     * Wraps a class type with Jest mock type definitions.
+     */
+    type MockedClass<T extends ClassLike> = JestMockedClass<T>;
+    /**
+     * Wraps a function type with Jest mock type definitions.
+     */
+    type MockedFunction<T extends FunctionLike> = JestMockedFunction<T>;
+    /**
+     * Wraps an object type with Jest mock type definitions.
+     */
+    type MockedObject<T extends object> = JestMockedObject<T>;
+
+    type MockInstance<T, Y extends any[]> = JestMockInstance<(...args: Y) => T>;
+
+    interface Mock<T = any, Y extends any[] = any>
+      extends Function, // eslint-disable-line @typescript-eslint/ban-types
+        MockInstance<T, Y> {
+      new (...args: Y): T;
+      (...args: Y): T;
+    }
+
+    interface CustomMatcherResult {
+      pass: boolean;
+      message: string | (() => string);
+    }
+
+    type SpyInstance<T, Y extends any[]> = JestSpyInstance<(...args: Y) => T>;
+
+    // Extension point for jest matchers
+    interface Expect {}
+
+    // Extension point for jest matchers
+    interface Matchers<R> {}
+  }
+}
diff --git a/test/util.ts b/test/util.ts
index a3189ac25548c4621b787406a5c9055d07132ef4..bb02d434fdaa39b7855ba10debe5c899d16775f4 100644
--- a/test/util.ts
+++ b/test/util.ts
@@ -16,8 +16,8 @@ import { regEx } from '../lib/util/regex';
  * Simple wrapper for getting mocked version of a module
  * @param module module which is mocked by `jest.mock`
  */
-export function mocked<T extends object>(module: T): jest.MockedObject<T> {
-  return module as jest.MockedObject<T>;
+export function mocked<T extends object>(module: T): jest.Mocked<T> {
+  return jest.mocked(module);
 }
 
 /**
@@ -41,15 +41,15 @@ export function partial(obj: unknown = {}): unknown {
   return obj;
 }
 
-export const fs = mocked(_fs);
-export const git = mocked(_git);
+export const fs = jest.mocked(_fs);
+export const git = jest.mocked(_git);
 
 // TODO: fix types, jest / typescript is using wrong overload (#22198)
-export const platform = mocked(partial<Required<Platform>>(_platform));
-export const scm = mocked(_scm);
-export const env = mocked(_env);
-export const hostRules = mocked(_hostRules);
-export const logger = mocked(_logger);
+export const platform = jest.mocked(partial<Required<Platform>>(_platform));
+export const scm = jest.mocked(_scm);
+export const env = jest.mocked(_env);
+export const hostRules = jest.mocked(_hostRules);
+export const logger = jest.mocked(_logger);
 
 export type { RenovateConfig };