Как мне издеваться над ES-модулями в NodeJS? - PullRequest
0 голосов
/ 26 июня 2018

Скажем, я реализовал модуль следующим образом:

import { foo } from 'dep1'

export const bar = () => foo()

Как бы я высмеял dep1, чтобы я мог провести модульный тест bar?

1 Ответ

0 голосов
/ 26 июня 2018

Один из возможных подходов может использовать зацепки загрузчика модуля ES.

Скажите, что dep1 содержит рабочий код, и мы хотим его высмеять. Я хотел бы создать файл с именем mymodule.mocks.mjs, где я буду издеваться foo:

// Regular mymodule.mjs
import { foo } from 'dep1'

export const bar = () => foo()

// Mocked mymodule.mocks.mjs

// dep1.foo() returns string
export const bar = () => 'whatever'

Теперь мы сможем загрузить mymodule.mocks.mjs, когда во время тестового запуска запрашивается mymodule.mjs.

Итак, мы реализуем testModuleLoader.mjs

Вот пользовательский обработчик загрузчика модулей, который реализует соглашение *.mocks.mjs:

import { existsSync } from 'fs'
import { dirname, extname, basename, join } from 'path'
import { parse } from 'url'

// The 'specifier' is the name or path that we provide
// when we import a module (i.e. import { x } from '[[specifier]]')
export function resolve (
   specifier,
   parentModuleURL,
   defaultResolver
) {
   // For built-ins
   if ( !parentModuleURL )
      return defaultResolver ( specifier, parentModuleURL )

   // If the specifier has no extension we provide the
   // Michael Jackson extension as the default one
   const moduleExt = extname ( specifier ) || '.mjs'
   const moduleDir = dirname ( specifier )
   const { pathname: parentModulePath } = parse (
      parentModuleURL
   )
   const fileName = basename ( specifier, moduleExt )

   // We build the possible mocks' module file path
   const mockFilePath = join (
      dirname ( parentModulePath ),
      moduleDir,
      `${fileName}.mocks${moduleExt}`
   )

   // If there's a file which ends with '.mocks.mjs'
   // we resolve that module instead of the regular one
   if ( existsSync ( mockFilePath ) )
      return defaultResolver ( mockFilePath, parentModuleURL )

   return defaultResolver ( specifier, parentModuleURL )
}

Используя его

Это просто предоставление node:

node --experimental-modules --loader ./path/to/testModuleLoader.mjs ./path/to/app.mjs

Подробнее о крюках загрузчика модуля ES.

...