Skip to content

Commit

Permalink
chore: cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
sheremet-va committed Jan 3, 2024
1 parent cd1d7e4 commit d6c1b83
Show file tree
Hide file tree
Showing 4 changed files with 13 additions and 34 deletions.
28 changes: 2 additions & 26 deletions docs/guide/common-errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ export default defineConfig({

## Cannot mock "./mocked-file.js" because it is already loaded

This error happens when `vi.mock` or `vi.doMock` methods are called on modules that were already loaded. Vitest throws this error because this call has no effect because cached modules are preferred.
This error happens when `vi.mock` method is called on a module that was already loaded. Vitest throws this error because this call has no effect since cached modules are preferred.

If you are getting this error for `vi.mock`, remember that `vi.mock` is always hoisted - it means that the module was loaded before the test file started executing - most likely in a setup file. To fix the error, remove the import or clear the cache at the end of a setup file - beware that setup file and your test file will reference different modules in that case.
Remember that `vi.mock` is always hoisted - it means that the module was loaded before the test file started executing - most likely in a setup file. To fix the error, remove the import or clear the cache at the end of a setup file - beware that setup file and your test file will reference different modules in that case.

```ts
// setupFile.js
Expand All @@ -58,27 +58,3 @@ sideEffect()

vi.resetModules()
```

If you are getting this error with `vi.doMock`, it means the file was already imported during test file execution or inside the setup file. If it was imported in the setup file, follow instruction from the previous paragraph. Otherwise it is possible that you are testing different module behaviours - so make sure to call `vi.resetModules` before mocking a module:

```ts
import { beforeEach, it, vi } from 'vitest'

beforeEach(() => {
vi.resetModules() // this will reset all modules cache
})

it('total is big', async () => {
vi.doMock('./mocked-file.js', () => ({ total: 100 }))

const { total } = await import('./mocked-file.js')
expect(total).toBe(100)
})

it('total is bigger', async () => {
vi.doMock('./mocked-file.js', () => ({ total: 200 }))

const { total } = await import('./mocked-file.js')
expect(total).toBe(200)
})
```
2 changes: 2 additions & 0 deletions packages/vitest/src/integrations/vi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,7 @@ function createVitest(): VitestUtils {
path,
importer,
factory ? () => factory(() => _mocker.importActual(path, importer, _mocker.getMockContext().callstack)) : undefined,
true,
)
},

Expand All @@ -496,6 +497,7 @@ function createVitest(): VitestUtils {
path,
importer,
factory ? () => factory(() => _mocker.importActual(path, importer, _mocker.getMockContext().callstack)) : undefined,
false,
)
},

Expand Down
16 changes: 8 additions & 8 deletions packages/vitest/src/runtime/mocker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ export class VitestMocker {
if (mock.type === 'unmock')
this.unmockPath(fsPath)
if (mock.type === 'mock')
this.mockPath(mock.id, fsPath, external, mock.factory)
this.mockPath(mock.id, fsPath, external, mock.factory, mock.throwIfCached)
}))

VitestMocker.pendingIds = []
Expand Down Expand Up @@ -407,13 +407,13 @@ export class VitestMocker {
this.deleteCachedItem(id)
}

public mockPath(originalId: string, path: string, external: string | null, factory?: MockFactory) {
const suitefile = this.getSuiteFilepath()
public mockPath(originalId: string, path: string, external: string | null, factory: MockFactory | undefined, throwIfExists: boolean) {
const id = this.normalizePath(path)

if (this.moduleCache.has(id))
if (throwIfExists && this.moduleCache.has(id))
throw new Error(`[vitest] Cannot mock "${originalId}" because it is already loaded. Did you import it in a setup file?\n\nPlease, remove the import if you want static imports to be mocked, or clear module cache by calling "vi.resetModules()" before mocking if you are going to import the file again. See: https://vitest.dev/guide/common-errors.html#cannot-mock-mocked-file.js-because-it-is-already-loaded`)

const suitefile = this.getSuiteFilepath()
const mocks = this.mockMap.get(suitefile) || {}
const resolves = this.resolveCache.get(suitefile) || {}

Expand Down Expand Up @@ -487,11 +487,11 @@ export class VitestMocker {
return mock
}

public queueMock(id: string, importer: string, factory?: MockFactory) {
VitestMocker.pendingIds.push({ type: 'mock', id, importer, factory })
public queueMock(id: string, importer: string, factory?: MockFactory, throwIfCached = false) {
VitestMocker.pendingIds.push({ type: 'mock', id, importer, factory, throwIfCached })
}

public queueUnmock(id: string, importer: string) {
VitestMocker.pendingIds.push({ type: 'unmock', id, importer })
public queueUnmock(id: string, importer: string, throwIfCached = false) {
VitestMocker.pendingIds.push({ type: 'unmock', id, importer, throwIfCached })
}
}
1 change: 1 addition & 0 deletions packages/vitest/src/types/mocker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ export interface PendingSuiteMock {
id: string
importer: string
type: 'mock' | 'unmock'
throwIfCached: boolean
factory?: MockFactory
}

0 comments on commit d6c1b83

Please sign in to comment.