diff --git a/docs/api/vi.md b/docs/api/vi.md
index 1a0d99c58..1f040959d 100644
--- a/docs/api/vi.md
+++ b/docs/api/vi.md
@@ -1051,7 +1051,7 @@ vi.useRealTimers()
### vi.useFakeTimers
```ts
-function useFakeTimers(config?: FakeTimerInstallOpts): Vitest
+function useFakeTimers(config?: FakeTimersConfig): Vitest
```
To enable mocking timers, you need to call this method. It will wrap all further calls to timers (such as `setTimeout`, `setInterval`, `clearTimeout`, `clearInterval`, `setImmediate`, `clearImmediate`, and `Date`) until [`vi.useRealTimers()`](#vi-userealtimers) is called.
@@ -1065,6 +1065,16 @@ The implementation is based internally on [`@sinonjs/fake-timers`](https://githu
But you can enable it by specifying the option in `toFake` argument: `vi.useFakeTimers({ toFake: ['nextTick', 'queueMicrotask'] })`.
:::
+You can use `toFake` to specify which timers to mock, or `toNotFake` to specify which timers to keep native. Note that `toFake` and `toNotFake` cannot be specified together.
+
+```ts
+// only mock setTimeout and clearTimeout
+vi.useFakeTimers({ toFake: ['setTimeout', 'clearTimeout'] })
+
+// mock all timers except setInterval
+vi.useFakeTimers({ toNotFake: ['setInterval'] })
+```
+
### vi.setTimerTickMode 4.1.0 {#vi-settimertickmode}
- **Type:** `(mode: 'manual' | 'nextTimerAsync') => Vitest | (mode: 'interval', interval?: number) => Vitest`
diff --git a/docs/config/faketimers.md b/docs/config/faketimers.md
index 68b43e1c2..2336bc3c9 100644
--- a/docs/config/faketimers.md
+++ b/docs/config/faketimers.md
@@ -5,7 +5,7 @@ outline: deep
# fakeTimers
-- **Type:** `FakeTimerInstallOpts`
+- **Type:** `FakeTimerConfig`
Options that Vitest will pass down to [`@sinon/fake-timers`](https://npmx.dev/package/@sinonjs/fake-timers) when using [`vi.useFakeTimers()`](/api/vi#vi-usefaketimers).
@@ -21,12 +21,23 @@ Installs fake timers with the specified Unix epoch.
- **Type:** `('setTimeout' | 'clearTimeout' | 'setImmediate' | 'clearImmediate' | 'setInterval' | 'clearInterval' | 'Date' | 'nextTick' | 'hrtime' | 'requestAnimationFrame' | 'cancelAnimationFrame' | 'requestIdleCallback' | 'cancelIdleCallback' | 'performance' | 'queueMicrotask')[]`
- **Default:** everything available globally except `nextTick` and `queueMicrotask`
-An array with names of global methods and APIs to fake.
-
-To only mock `setTimeout()` and `nextTick()`, specify this property as `['setTimeout', 'nextTick']`.
+An array with names of global methods and APIs to fake. For example, to only mock `setTimeout()` and `nextTick()`, specify this property as `['setTimeout', 'nextTick']`.
Mocking `nextTick` is not supported when running Vitest inside `node:child_process` by using `--pool=forks`. NodeJS uses `process.nextTick` internally in `node:child_process` and hangs when it is mocked. Mocking `nextTick` is supported when running Vitest with `--pool=threads`.
+## fakeTimers.toNotFake
+
+- **Type:** `('setTimeout' | 'clearTimeout' | 'setImmediate' | 'clearImmediate' | 'setInterval' | 'clearInterval' | 'Date' | 'nextTick' | 'hrtime' | 'requestAnimationFrame' | 'cancelAnimationFrame' | 'requestIdleCallback' | 'cancelIdleCallback' | 'performance' | 'queueMicrotask')[]`
+- **Default:** `[]`
+
+An array with names of global methods and APIs to keep native. All other available timers will be mocked. For example, to keep `setInterval()` native and mock all other timers, specify this property as `['setInterval']`.
+
+Mocking `nextTick` is not supported when running Vitest inside `node:child_process` by using `--pool=forks`. When running with `--pool=forks`, Vitest automatically adds `nextTick` to the `toNotFake` array.
+
+::: warning
+Using both `toFake` and `toNotFake` together is not supported.
+:::
+
## fakeTimers.loopLimit
- **Type:** `number`
diff --git a/packages/vitest/package.json b/packages/vitest/package.json
index fa33c24a7..9046ad698 100644
--- a/packages/vitest/package.json
+++ b/packages/vitest/package.json
@@ -192,7 +192,7 @@
"@edge-runtime/vm": "^5.0.0",
"@jridgewell/trace-mapping": "catalog:",
"@opentelemetry/api": "^1.9.0",
- "@sinonjs/fake-timers": "15.0.0",
+ "@sinonjs/fake-timers": "15.3.2",
"@types/estree": "catalog:",
"@types/istanbul-lib-coverage": "catalog:",
"@types/istanbul-reports": "catalog:",
@@ -200,7 +200,6 @@
"@types/node": "^24.12.0",
"@types/picomatch": "^4.0.2",
"@types/prompts": "^2.4.9",
- "@types/sinonjs__fake-timers": "^15.0.1",
"@vitest/expect": "workspace:*",
"@vitest/snapshot": "workspace:*",
"acorn": "8.11.3",
diff --git a/packages/vitest/src/defaults.ts b/packages/vitest/src/defaults.ts
index 77bf14ffe..3d29a547f 100644
--- a/packages/vitest/src/defaults.ts
+++ b/packages/vitest/src/defaults.ts
@@ -88,7 +88,7 @@ export const configDefaults: Readonly<{
include: never[]
}
coverage: CoverageOptions
- fakeTimers: import('@sinonjs/fake-timers').FakeTimerInstallOpts
+ fakeTimers: import('@sinonjs/fake-timers').Config
maxConcurrency: number
dangerouslyIgnoreUnhandledErrors: boolean
typecheck: {
diff --git a/packages/vitest/src/integrations/mock/timers.ts b/packages/vitest/src/integrations/mock/timers.ts
index ae60e349a..fca90e896 100644
--- a/packages/vitest/src/integrations/mock/timers.ts
+++ b/packages/vitest/src/integrations/mock/timers.ts
@@ -6,9 +6,10 @@
*/
import type {
- FakeTimerInstallOpts,
- FakeTimerWithContext,
- InstalledClock,
+ Clock,
+ FakeMethod,
+ Config as FakeTimersConfig,
+ FakeTimers as FakeTimersContext,
} from '@sinonjs/fake-timers'
import { withGlobal } from '@sinonjs/fake-timers'
import { isChildProcess } from '../../runtime/utils'
@@ -16,7 +17,7 @@ import { mockDate, RealDate, resetDate } from './date'
export class FakeTimers {
private _global: typeof globalThis
- private _clock!: InstalledClock
+ private _clock!: Clock
// | _fakingTime | _fakingDate |
// +-------------+-------------+
// | false | falsy | initial
@@ -25,8 +26,8 @@ export class FakeTimers {
// | true | truthy | unreachable
private _fakingTime: boolean
private _fakingDate: Date | null
- private _fakeTimers: FakeTimerWithContext
- private _userConfig?: FakeTimerInstallOpts
+ private _fakeTimers: FakeTimersContext
+ private _userConfig?: FakeTimersConfig
private _now = RealDate.now
constructor({
@@ -34,7 +35,7 @@ export class FakeTimers {
config,
}: {
global: typeof globalThis
- config: FakeTimerInstallOpts
+ config: FakeTimersConfig
}) {
this._userConfig = config
@@ -154,22 +155,28 @@ export class FakeTimers {
this._clock.uninstall()
}
- const toFake = Object.keys(this._fakeTimers.timers)
- // Do not mock timers internally used by node by default. It can still be mocked through userConfig.
- .filter(
- timer => timer !== 'nextTick' && timer !== 'queueMicrotask',
- ) as (keyof FakeTimerWithContext['timers'])[]
-
- if (this._userConfig?.toFake?.includes('nextTick') && isChildProcess()) {
+ let toFake = this._userConfig?.toFake
+ if (isChildProcess() && toFake?.includes('nextTick')) {
throw new Error(
'process.nextTick cannot be mocked inside child_process',
)
}
+ let toNotFake = this._userConfig?.toNotFake
+ if (toFake === undefined && toNotFake === undefined) {
+ // Do not mock timers internally used by node by default. It can still be mocked through userConfig.
+ toFake = (Object.keys(this._fakeTimers.timers) as FakeMethod[])
+ .filter(timer => timer !== 'nextTick' && timer !== 'queueMicrotask')
+ }
+ if (isChildProcess() && toNotFake && !toNotFake.includes('nextTick')) {
+ toNotFake = [...toNotFake, 'nextTick']
+ }
+
this._clock = this._fakeTimers.install({
now: fakeDate,
...this._userConfig,
- toFake: this._userConfig?.toFake || toFake,
+ ...(toFake && { toFake }),
+ ...(toNotFake && { toNotFake }),
ignoreMissingTimers: true,
})
@@ -228,7 +235,7 @@ export class FakeTimers {
}
}
- configure(config: FakeTimerInstallOpts): void {
+ configure(config: FakeTimersConfig): void {
this._userConfig = config
}
diff --git a/packages/vitest/src/integrations/vi.ts b/packages/vitest/src/integrations/vi.ts
index f8d94f99e..54f081de2 100644
--- a/packages/vitest/src/integrations/vi.ts
+++ b/packages/vitest/src/integrations/vi.ts
@@ -1,4 +1,4 @@
-import type { FakeTimerInstallOpts } from '@sinonjs/fake-timers'
+import type { Config as FakeTimersConfig } from '@sinonjs/fake-timers'
import type {
MaybeMocked,
MaybeMockedDeep,
@@ -27,7 +27,7 @@ export interface VitestUtils {
/**
* This method wraps all further calls to timers until [`vi.useRealTimers()`](https://vitest.dev/api/vi#vi-userealtimers) is called.
*/
- useFakeTimers: (config?: FakeTimerInstallOpts) => VitestUtils
+ useFakeTimers: (config?: FakeTimersConfig) => VitestUtils
/**
* Restores mocked timers to their original implementations. All timers that were scheduled before will be discarded.
*/
@@ -496,7 +496,7 @@ function createVitest(): VitestUtils {
const _envBooleans = ['PROD', 'DEV', 'SSR']
const utils: VitestUtils = {
- useFakeTimers(config?: FakeTimerInstallOpts) {
+ useFakeTimers(config?: FakeTimersConfig) {
if (isChildProcess()) {
if (
config?.toFake?.includes('nextTick')
diff --git a/packages/vitest/src/node/types/config.ts b/packages/vitest/src/node/types/config.ts
index 020384634..452d86616 100644
--- a/packages/vitest/src/node/types/config.ts
+++ b/packages/vitest/src/node/types/config.ts
@@ -1,4 +1,4 @@
-import type { FakeTimerInstallOpts } from '@sinonjs/fake-timers'
+import type { Config as FakeTimersConfig } from '@sinonjs/fake-timers'
import type { PrettyFormatOptions } from '@vitest/pretty-format'
import type { SequenceHooks, SequenceSetupFiles, SerializableRetry, TestTagDefinition } from '@vitest/runner'
import type { SnapshotStateOptions } from '@vitest/snapshot'
@@ -617,7 +617,7 @@ export interface InlineConfig {
/**
* Options for @sinon/fake-timers
*/
- fakeTimers?: FakeTimerInstallOpts
+ fakeTimers?: FakeTimersConfig
/**
* Custom handler for console.log in tests.
diff --git a/packages/vitest/src/runtime/config.ts b/packages/vitest/src/runtime/config.ts
index c1d6c0418..a8e2e298b 100644
--- a/packages/vitest/src/runtime/config.ts
+++ b/packages/vitest/src/runtime/config.ts
@@ -1,4 +1,4 @@
-import type { FakeTimerInstallOpts } from '@sinonjs/fake-timers'
+import type { Config as FakeTimersConfig } from '@sinonjs/fake-timers'
import type { PrettyFormatOptions } from '@vitest/pretty-format'
import type { SequenceHooks, SequenceSetupFiles, SerializableRetry, TestTagDefinition } from '@vitest/runner'
import type { SnapshotEnvironment, SnapshotUpdateState } from '@vitest/snapshot'
@@ -34,7 +34,7 @@ export interface SerializedConfig {
unstubGlobals: boolean
unstubEnvs: boolean
// TODO: make optional
- fakeTimers: FakeTimerInstallOpts
+ fakeTimers: FakeTimersConfig
maxConcurrency: number
defines: Record
expect: {
diff --git a/patches/@sinonjs__fake-timers@15.0.0.patch b/patches/@sinonjs__fake-timers@15.3.2.patch
similarity index 86%
rename from patches/@sinonjs__fake-timers@15.0.0.patch
rename to patches/@sinonjs__fake-timers@15.3.2.patch
index ec8ed6bd8..779976520 100644
--- a/patches/@sinonjs__fake-timers@15.0.0.patch
+++ b/patches/@sinonjs__fake-timers@15.3.2.patch
@@ -1,5 +1,5 @@
diff --git a/src/fake-timers-src.js b/src/fake-timers-src.js
-index a9bcfd1ca..942539085 100644
+index 7d4cfa1b6b8aebc8575e08bd432f8f8ca43d3c4f..09d12bec356aa1048f09771e915075fdecb065b9 100644
--- a/src/fake-timers-src.js
+++ b/src/fake-timers-src.js
@@ -2,14 +2,14 @@
@@ -11,16 +11,16 @@ index a9bcfd1ca..942539085 100644
try {
- timersModule = require("timers");
+ timersModule = __vitest_required__.timers;
- } catch (e) {
+ } catch {
// ignored
}
try {
- timersPromisesModule = require("timers/promises");
+ timersPromisesModule = __vitest_required__.timersPromises;
- } catch (e) {
+ } catch {
// ignored
}
-@@ -197,7 +197,7 @@ function withGlobal(_global) {
+@@ -510,7 +510,7 @@ function withGlobal(_global) {
isPresent.hrtime && typeof _global.process.hrtime.bigint === "function";
isPresent.nextTick =
_global.process && typeof _global.process.nextTick === "function";
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 928275647..8034554ba 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -180,9 +180,9 @@ overrides:
vitest: workspace:*
patchedDependencies:
- '@sinonjs/fake-timers@15.0.0':
- hash: 8f3309cba0158608885141fb640e96b064570f7399136966ff13523bdaf678b2
- path: patches/@sinonjs__fake-timers@15.0.0.patch
+ '@sinonjs/fake-timers@15.3.2':
+ hash: 5513cab538aec68ba021f971d90c859c11658db640ba76d316c8df0d2915b0b0
+ path: patches/@sinonjs__fake-timers@15.3.2.patch
acorn@8.11.3:
hash: 62f89b815dbd769c8a4d5b19b1f6852f28922ecb581d876c8a8377d05c2483c4
path: patches/acorn@8.11.3.patch
@@ -1115,8 +1115,8 @@ importers:
specifier: ^1.9.0
version: 1.9.0
'@sinonjs/fake-timers':
- specifier: 15.0.0
- version: 15.0.0(patch_hash=8f3309cba0158608885141fb640e96b064570f7399136966ff13523bdaf678b2)
+ specifier: 15.3.2
+ version: 15.3.2(patch_hash=5513cab538aec68ba021f971d90c859c11658db640ba76d316c8df0d2915b0b0)
'@types/estree':
specifier: 'catalog:'
version: 1.0.8
@@ -1138,9 +1138,6 @@ importers:
'@types/prompts':
specifier: ^2.4.9
version: 2.4.9
- '@types/sinonjs__fake-timers':
- specifier: ^15.0.1
- version: 15.0.1
'@vitest/expect':
specifier: workspace:*
version: link:../expect
@@ -4841,11 +4838,8 @@ packages:
'@sinonjs/commons@3.0.1':
resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==}
- '@sinonjs/fake-timers@15.0.0':
- resolution: {integrity: sha512-dlUB2oL+hDIYkIq/OWFBDhQAuU6kDey3eeMiYpVb7UXHhkMq/r1HloKXAbJwJZpYWkFWsydLjMqDpueMUEOjXQ==}
-
- '@sinonjs/fake-timers@15.1.1':
- resolution: {integrity: sha512-cO5W33JgAPbOh07tvZjUOJ7oWhtaqGHiZw+11DPbyqh2kHTBc3eF/CjJDeQ4205RLQsX6rxCuYOroFQwl7JDRw==}
+ '@sinonjs/fake-timers@15.3.2':
+ resolution: {integrity: sha512-mrn35Jl2pCpns+mE3HaZa1yPN5EYCRgiMI+135COjr2hr8Cls9DXqIZ57vZe2cz7y2XVSq92tcs6kGQcT1J8Rw==}
'@sinonjs/samsam@9.0.3':
resolution: {integrity: sha512-ZgYY7Dc2RW+OUdnZ1DEHg00lhRt+9BjymPKHog4PRFzr1U3MbK57+djmscWyKxzO1qfunHqs4N45WWyKIFKpiQ==}
@@ -5206,9 +5200,6 @@ packages:
'@types/resolve@1.20.2':
resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==}
- '@types/sinonjs__fake-timers@15.0.1':
- resolution: {integrity: sha512-Ko2tjWJq8oozHzHV+reuvS5KYIRAokHnGbDwGh/J64LntgpbuylF74ipEL24HCyRjf9FOlBiBHWBR1RlVKsI1w==}
-
'@types/sinonjs__fake-timers@8.1.5':
resolution: {integrity: sha512-mQkU2jY8jJEF7YHjHvsQO8+3ughTL1mcnn96igfhONmR+fUPSKIkefQYpSe8bsly2Ep7oQbn/6VG5/9/0qcArQ==}
@@ -13256,11 +13247,7 @@ snapshots:
dependencies:
type-detect: 4.0.8
- '@sinonjs/fake-timers@15.0.0(patch_hash=8f3309cba0158608885141fb640e96b064570f7399136966ff13523bdaf678b2)':
- dependencies:
- '@sinonjs/commons': 3.0.1
-
- '@sinonjs/fake-timers@15.1.1':
+ '@sinonjs/fake-timers@15.3.2(patch_hash=5513cab538aec68ba021f971d90c859c11658db640ba76d316c8df0d2915b0b0)':
dependencies:
'@sinonjs/commons': 3.0.1
@@ -13604,8 +13591,6 @@ snapshots:
'@types/resolve@1.20.2': {}
- '@types/sinonjs__fake-timers@15.0.1': {}
-
'@types/sinonjs__fake-timers@8.1.5': {}
'@types/statuses@2.0.6': {}
@@ -18701,7 +18686,7 @@ snapshots:
sinon@21.0.3:
dependencies:
'@sinonjs/commons': 3.0.1
- '@sinonjs/fake-timers': 15.1.1
+ '@sinonjs/fake-timers': 15.3.2(patch_hash=5513cab538aec68ba021f971d90c859c11658db640ba76d316c8df0d2915b0b0)
'@sinonjs/samsam': 9.0.3
diff: 8.0.3
supports-color: 7.2.0
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
index e55a5f21c..74eb8051c 100644
--- a/pnpm-workspace.yaml
+++ b/pnpm-workspace.yaml
@@ -39,7 +39,7 @@ overrides:
vite: $vite
vitest: workspace:*
patchedDependencies:
- '@sinonjs/fake-timers@15.0.0': patches/@sinonjs__fake-timers@15.0.0.patch
+ '@sinonjs/fake-timers@15.3.2': patches/@sinonjs__fake-timers@15.3.2.patch
acorn@8.11.3: patches/acorn@8.11.3.patch
cac@6.7.14: patches/cac@6.7.14.patch
istanbul-lib-instrument: patches/istanbul-lib-instrument.patch
diff --git a/test/unit/test/fixtures/timers.suite.ts b/test/unit/test/fixtures/timers.suite.ts
index 1f26dbedd..9122734ae 100644
--- a/test/unit/test/fixtures/timers.suite.ts
+++ b/test/unit/test/fixtures/timers.suite.ts
@@ -51,7 +51,7 @@ describe('FakeTimers', () => {
expect(global.clearInterval).not.toBe(undefined)
})
- it.skipIf(isChildProcess)('mocks process.nextTick if it exists on global', () => {
+ it.skipIf(isChildProcess)('mocks process.nextTick when toFake includes nextTick', () => {
const origNextTick = () => {}
const global = {
Date: FakeDate,
@@ -81,7 +81,7 @@ describe('FakeTimers', () => {
expect(global.process.nextTick).toBe(origNextTick)
})
- it.runIf(isChildProcess)('throws when is child_process and tries to mock nextTick', () => {
+ it.runIf(isChildProcess)('throws when is child_process and toFake includes nextTick', () => {
const global = { Date: FakeDate, process, setTimeout, clearTimeout }
const timers = new FakeTimers({ global, config: { toFake: ['nextTick'] } })
@@ -135,6 +135,90 @@ describe('FakeTimers', () => {
expect(global.setImmediate).toBeUndefined();
expect(global.clearImmediate).toBeUndefined();
})
+
+ it('leaves listed methods native when toNotFake is used', () => {
+ const origSetTimeout = setTimeout
+ const origSetImmediate = () => {}
+ const origClearImmediate = () => {}
+ const global = {
+ Date: FakeDate,
+ clearImmediate: origClearImmediate,
+ clearTimeout,
+ setImmediate: origSetImmediate,
+ setTimeout,
+ }
+ const timers = new FakeTimers({ global, config: { toNotFake: ['setImmediate', 'clearImmediate', 'nextTick'] } })
+ timers.useFakeTimers()
+ expect(global.setTimeout).not.toBe(origSetTimeout)
+ expect(global.setImmediate).toBe(origSetImmediate)
+ expect(global.clearImmediate).toBe(origClearImmediate)
+ })
+
+ it.skipIf(isChildProcess)('mocks process.nextTick when toNotFake does not include nextTick', () => {
+ const origNextTick = () => {}
+ const global = {
+ Date: FakeDate,
+ clearTimeout,
+ process: {
+ nextTick: origNextTick,
+ },
+ setTimeout,
+ }
+ const timers = new FakeTimers({ global, config: { toNotFake: [] } })
+ timers.useFakeTimers()
+ expect(global.process.nextTick).not.toBe(origNextTick)
+ })
+
+ it.runIf(isChildProcess)('does not mock process.nextTick when toNotFake does not include nextTick and is child_process', () => {
+ const origNextTick = () => {}
+ const global = {
+ Date: FakeDate,
+ clearTimeout,
+ process: {
+ nextTick: origNextTick,
+ },
+ setTimeout,
+ }
+ const timers = new FakeTimers({ global, config: { toNotFake: [] } })
+ timers.useFakeTimers()
+ expect(global.process.nextTick).toBe(origNextTick)
+ })
+
+ it.skipIf(isChildProcess)('does not mock process.nextTick when toNotFake includes nextTick', () => {
+ const origNextTick = () => {}
+ const global = {
+ Date: FakeDate,
+ clearTimeout,
+ process: {
+ nextTick: origNextTick,
+ },
+ setTimeout,
+ }
+ const timers = new FakeTimers({ global, config: { toNotFake: ['nextTick'] } })
+ timers.useFakeTimers()
+ expect(global.process.nextTick).toBe(origNextTick)
+ })
+
+ it("toFake and toNotFake cannot be used together", () => {
+ const global = {
+ Date: FakeDate,
+ setTimeout,
+ clearTimeout,
+ setInterval,
+ clearInterval,
+ }
+ const timers = new FakeTimers({
+ global,
+ config: {
+ toFake: [],
+ toNotFake: [],
+ },
+ })
+ expect(() => timers.useFakeTimers())
+ .toThrowErrorMatchingInlineSnapshot(
+ `[TypeError: config.toFake and config.toNotFake cannot be used together]`
+ )
+ })
})
describe('runAllTicks', () => {
@@ -1138,8 +1222,8 @@ describe('FakeTimers', () => {
'mock1',
'mock2',
'mock2',
- 'mock3',
'mock5',
+ 'mock3',
'mock1',
'mock2',
])
@@ -1246,8 +1330,8 @@ describe('FakeTimers', () => {
'mock1',
'mock2',
'mock2',
- 'mock3',
'mock5',
+ 'mock3',
'mock1',
'mock2',
])