Skip to content

Commit

Permalink
fix: can mock non-existent paths and virtual modules via __mocks__ (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
sheremet-va committed May 13, 2022
1 parent 7f068b5 commit c491fb4
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 3 deletions.
1 change: 1 addition & 0 deletions examples/mocks/__mocks__/virtual-module.ts
@@ -0,0 +1 @@
export const value = 'folder'
1 change: 1 addition & 0 deletions examples/mocks/__mocks__/vscode-mocks.ts
@@ -0,0 +1 @@
export const folder = true
24 changes: 24 additions & 0 deletions examples/mocks/test/virtual.test.ts
@@ -0,0 +1,24 @@
// @ts-expect-error vscode is not installed
import * as vscodeMocks from 'vscode-mocks'
// @ts-expect-error vscode is not installed
import * as vscodeFactory from 'vscode-factory'
// @ts-expect-error virtual module
import * as virtual from 'virtual-module'

vi.mock('vscode-mocks')
vi.mock('vscode-factory', () => {
return { factory: true }
})
vi.mock('virtual-module')

it('mocks not installed in mocks folder', () => {
expect(vscodeMocks.folder).toBe(true)
})

it('mocks not installed in mocks factory', () => {
expect(vscodeFactory.factory).toBe(true)
})

it('mocks virtual modules in mocks folder', () => {
expect(virtual.value).toBe('folder')
})
16 changes: 16 additions & 0 deletions examples/mocks/vite.config.ts
Expand Up @@ -4,6 +4,22 @@ import { defineConfig } from 'vite'

// https://vitejs.dev/config/
export default defineConfig({
plugins: [
{
name: 'example',
resolveId(source) {
if (source === 'virtual-module')
return source
},
load(id) {
if (id === 'virtual-module') {
return `
export const value = 'original';
`
}
},
},
],
test: {
globals: true,
environment: 'node',
Expand Down
10 changes: 7 additions & 3 deletions packages/vitest/src/runtime/mocker.ts
Expand Up @@ -63,9 +63,13 @@ export class VitestMocker {

private async resolvePath(id: string, importer: string) {
const path = await this.options.resolveId!(id, importer)
// external is node_module or unresolved module
// for example, some people mock "vscode" and don't have it installed
const external = path == null || path.id.includes('/node_modules/') ? id : null

return {
path: normalizeRequestId(path?.id || id),
external: path?.id.includes('/node_modules/') ? id : null,
external,
}
}

Expand Down Expand Up @@ -115,15 +119,15 @@ export class VitestMocker {

// it's a node_module alias
// all mocks should be inside <root>/__mocks__
if (external || isNodeBuiltin(mockPath)) {
if (external || isNodeBuiltin(mockPath) || !existsSync(mockPath)) {
const mockDirname = dirname(path) // for nested mocks: @vueuse/integration/useJwt
const baseFilename = basename(path)
const mockFolder = resolve(this.root, '__mocks__', mockDirname)

if (!existsSync(mockFolder))
return null

const files = readdirSync(mockFolder)
const baseFilename = basename(path)

for (const file of files) {
const [basename] = file.split('.')
Expand Down

0 comments on commit c491fb4

Please sign in to comment.