Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/442.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Svelte 3:单元测试时无法导入模块_Javascript_Unit Testing_Jestjs_Svelte_Svelte 3 - Fatal编程技术网

Javascript Svelte 3:单元测试时无法导入模块

Javascript Svelte 3:单元测试时无法导入模块,javascript,unit-testing,jestjs,svelte,svelte-3,Javascript,Unit Testing,Jestjs,Svelte,Svelte 3,我正试着用笑话测试一个苗条的组件。此组件在浏览器中工作正常,但导入模块时单元测试失败 例如,在运行Jest时,从“uuid”导入uuid编译为const{default:uuid}=require(“uuid”),调用uuid.v4()会导致TypeError:无法读取未定义的属性“v4”。当我使用import*作为来自“uuid”的uuid或const uuid=require('uuid')时,Jest单元测试通过,但在浏览器中不起作用 我如何处理这个问题?任何信息都会大有帮助。多谢各位 p

我正试着用笑话测试一个苗条的组件。此组件在浏览器中工作正常,但导入模块时单元测试失败

例如,在运行Jest时,
从“uuid”导入uuid
编译为
const{default:uuid}=require(“uuid”),调用
uuid.v4()
会导致
TypeError:无法读取未定义的属性“v4”
。当我使用
import*作为来自“uuid”的uuid
const uuid=require('uuid')
时,Jest单元测试通过,但在浏览器中不起作用

我如何处理这个问题?任何信息都会大有帮助。多谢各位

package.json:

{
  "name": "svelte-app",
  "version": "1.0.0",
  "scripts": {
    "build": "rollup -c",
    "dev": "rollup -c -w",
    "start": "firebase serve --only hosting"
  },
  "devDependencies": {
    "@rollup/plugin-json": "^4.0.0",
    "@testing-library/jest-dom": "^5.1.1",
    "@testing-library/svelte": "^1.11.0",
    "bulma": "^0.8.0",
    "eslint": "^6.7.0",
    "eslint-config-standard": "^14.1.0",
    "eslint-plugin-import": "^2.18.2",
    "eslint-plugin-jest": "^23.0.4",
    "eslint-plugin-node": "^10.0.0",
    "eslint-plugin-promise": "^4.2.1",
    "eslint-plugin-standard": "^4.0.1",
    "eslint-plugin-svelte3": "^2.7.3",
    "jest-transform-svelte": "^2.1.1",
    "node-sass": "^4.13.1",
    "rollup": "^1.12.0",
    "rollup-jest": "0.0.2",
    "rollup-plugin-commonjs": "^10.0.0",
    "rollup-plugin-livereload": "^1.0.0",
    "rollup-plugin-node-builtins": "^2.1.2",
    "rollup-plugin-node-globals": "^1.4.0",
    "rollup-plugin-node-resolve": "^5.2.0",
    "rollup-plugin-svelte": "^5.0.3",
    "rollup-plugin-terser": "^5.1.2",
    "sirv-cli": "^0.4.5",
    "svelma": "^0.3.2",
    "svelte": "^3.18.2",
    "svelte-preprocess": "^3.4.0"
  },
  "dependencies": {
    "firebase": "^7.8.2"
  },
  "private": true
}
rollup.config.js

import json from '@rollup/plugin-json'
import commonjs from 'rollup-plugin-commonjs'
import builtins from 'rollup-plugin-node-builtins'
import globals from 'rollup-plugin-node-globals'
import livereload from 'rollup-plugin-livereload'
import resolve from 'rollup-plugin-node-resolve'
import svelte from 'rollup-plugin-svelte'
import { terser } from 'rollup-plugin-terser'
import preprocess from 'svelte-preprocess'

const production = !process.env.ROLLUP_WATCH

export default {
  input: 'src/main.js',
  output: {
    sourcemap: true,
    format: 'iife',
    name: 'app',
    file: 'public/build/bundle.js',
  },
  plugins: [
    // https://github.com/rollup/plugins/tree/master/packages/json
    json(),

    svelte({
      // enable run-time checks when not in production
      dev: !production,
      // we'll extract any component CSS out into
      // a separate file — better for performance
      css: css => {
        css.write('public/build/bundle.css')
      },
      preprocess: preprocess(),
    }),

    // If you have external dependencies installed from
    // npm, you'll most likely need these plugins. In
    // some cases you'll need additional configuration —
    // consult the documentation for details:
    // https://github.com/rollup/rollup-plugin-commonjs
    resolve({
      browser: true,
      dedupe: importee => importee === 'svelte' || importee.startsWith('svelte/'),
    }),
    commonjs(),
    globals(),
    builtins(),

    // In dev mode, call `npm run start` once
    // the bundle has been generated
    !production && serve(),

    // Watch the `public` directory and refresh the
    // browser on changes when not in production
    !production && livereload('public'),

    // If we're building for production (npm run build
    // instead of npm run dev), minify
    production && terser(),
  ],
  watch: {
    clearScreen: false,
  },
}

function serve () {
  let started = false

  return {
    writeBundle () {
      if (!started) {
        started = true

        require('child_process').spawn('npm', ['run', 'start'], {
          stdio: ['ignore', 'inherit', 'inherit'],
          shell: true,
        })
      }
    },
  }
}
const sveltePreprocess = require('svelte-preprocess')

module.exports = {
  displayName: { name: 'web', color: 'magentaBright' },
  moduleFileExtensions: [
    'js',
    'json',
    'svelte',
  ],
  preset: 'rollup-jest',
  transform: {
    '\\.js$': 'rollup-jest',
    '\\.svelte$': ['jest-transform-svelte', { preprocess: sveltePreprocess(), debug: true }],
  },
  setupFilesAfterEnv: ['@testing-library/jest-dom/extend-expect'],
}
module.exports = {
  preset: 'jest-puppeteer', //ignore the preset part, I used for puppeteer
  transform: {
    '^.+\\.js?$': require.resolve('babel-jest'),
    "^.+\\.ts?$": "ts-jest" // this part is only required if you have typescript project
  }
};
const svelteJestPreprocessor = require('./svelteJestPreprocessor')
const sveltePreprocess = require('svelte-preprocess')

module.exports = {
  moduleFileExtensions: [
    'js',
    'json',
    'svelte',
  ],
  preset: 'rollup-jest',
  transform: {
    '\\.js$': 'rollup-jest',
    '\\.svelte$': ['jest-transform-svelte', {
      preprocess: [
        svelteJestPreprocessor(),
        sveltePreprocess(),
      ],
    }],
  },
  setupFilesAfterEnv: ['@testing-library/jest-dom/extend-expect'],
}
jest.config.js

import json from '@rollup/plugin-json'
import commonjs from 'rollup-plugin-commonjs'
import builtins from 'rollup-plugin-node-builtins'
import globals from 'rollup-plugin-node-globals'
import livereload from 'rollup-plugin-livereload'
import resolve from 'rollup-plugin-node-resolve'
import svelte from 'rollup-plugin-svelte'
import { terser } from 'rollup-plugin-terser'
import preprocess from 'svelte-preprocess'

const production = !process.env.ROLLUP_WATCH

export default {
  input: 'src/main.js',
  output: {
    sourcemap: true,
    format: 'iife',
    name: 'app',
    file: 'public/build/bundle.js',
  },
  plugins: [
    // https://github.com/rollup/plugins/tree/master/packages/json
    json(),

    svelte({
      // enable run-time checks when not in production
      dev: !production,
      // we'll extract any component CSS out into
      // a separate file — better for performance
      css: css => {
        css.write('public/build/bundle.css')
      },
      preprocess: preprocess(),
    }),

    // If you have external dependencies installed from
    // npm, you'll most likely need these plugins. In
    // some cases you'll need additional configuration —
    // consult the documentation for details:
    // https://github.com/rollup/rollup-plugin-commonjs
    resolve({
      browser: true,
      dedupe: importee => importee === 'svelte' || importee.startsWith('svelte/'),
    }),
    commonjs(),
    globals(),
    builtins(),

    // In dev mode, call `npm run start` once
    // the bundle has been generated
    !production && serve(),

    // Watch the `public` directory and refresh the
    // browser on changes when not in production
    !production && livereload('public'),

    // If we're building for production (npm run build
    // instead of npm run dev), minify
    production && terser(),
  ],
  watch: {
    clearScreen: false,
  },
}

function serve () {
  let started = false

  return {
    writeBundle () {
      if (!started) {
        started = true

        require('child_process').spawn('npm', ['run', 'start'], {
          stdio: ['ignore', 'inherit', 'inherit'],
          shell: true,
        })
      }
    },
  }
}
const sveltePreprocess = require('svelte-preprocess')

module.exports = {
  displayName: { name: 'web', color: 'magentaBright' },
  moduleFileExtensions: [
    'js',
    'json',
    'svelte',
  ],
  preset: 'rollup-jest',
  transform: {
    '\\.js$': 'rollup-jest',
    '\\.svelte$': ['jest-transform-svelte', { preprocess: sveltePreprocess(), debug: true }],
  },
  setupFilesAfterEnv: ['@testing-library/jest-dom/extend-expect'],
}
module.exports = {
  preset: 'jest-puppeteer', //ignore the preset part, I used for puppeteer
  transform: {
    '^.+\\.js?$': require.resolve('babel-jest'),
    "^.+\\.ts?$": "ts-jest" // this part is only required if you have typescript project
  }
};
const svelteJestPreprocessor = require('./svelteJestPreprocessor')
const sveltePreprocess = require('svelte-preprocess')

module.exports = {
  moduleFileExtensions: [
    'js',
    'json',
    'svelte',
  ],
  preset: 'rollup-jest',
  transform: {
    '\\.js$': 'rollup-jest',
    '\\.svelte$': ['jest-transform-svelte', {
      preprocess: [
        svelteJestPreprocessor(),
        sveltePreprocess(),
      ],
    }],
  },
  setupFilesAfterEnv: ['@testing-library/jest-dom/extend-expect'],
}

我一直面临着同样的问题,通过在测试文件中模拟模块并给它一个默认键,我找到了解决办法

jest.mock('uuid', () => ({
  default: {
    v4: jest.fn(),
  },
}))
另一种似乎有效的方法是在组件文件中分解导入

import { v4 as uuidv4 } from 'uuid'

这对我很有效。

问题似乎是jest在运行时构建代码时无法解析uuid。 这很明显,因为默认情况下,会忽略节点模块包

我遇到了类似的问题并解决了它。该方法是通过配置通知JEST,它还必须包括节点\单元模块包。在我的项目中,我使用了汇总插件babel。 这是babel插件配置

...
...
babel({
    extensions: [ '.js', '.mjs', '.html', '.svelte' ],
    runtimeHelpers: true,
    exclude: [ 'node_modules/@babel/**', 'node_modules/core-js/**' ],
    presets: [
      [
        '@babel/preset-env',
        {
          targets: '> 0.25%, not dead',
          useBuiltIns: 'usage',
          corejs: 3 
        }
      ]
    ]
  })
我还添加了babel jest,用于转换jest.config.js

import json from '@rollup/plugin-json'
import commonjs from 'rollup-plugin-commonjs'
import builtins from 'rollup-plugin-node-builtins'
import globals from 'rollup-plugin-node-globals'
import livereload from 'rollup-plugin-livereload'
import resolve from 'rollup-plugin-node-resolve'
import svelte from 'rollup-plugin-svelte'
import { terser } from 'rollup-plugin-terser'
import preprocess from 'svelte-preprocess'

const production = !process.env.ROLLUP_WATCH

export default {
  input: 'src/main.js',
  output: {
    sourcemap: true,
    format: 'iife',
    name: 'app',
    file: 'public/build/bundle.js',
  },
  plugins: [
    // https://github.com/rollup/plugins/tree/master/packages/json
    json(),

    svelte({
      // enable run-time checks when not in production
      dev: !production,
      // we'll extract any component CSS out into
      // a separate file — better for performance
      css: css => {
        css.write('public/build/bundle.css')
      },
      preprocess: preprocess(),
    }),

    // If you have external dependencies installed from
    // npm, you'll most likely need these plugins. In
    // some cases you'll need additional configuration —
    // consult the documentation for details:
    // https://github.com/rollup/rollup-plugin-commonjs
    resolve({
      browser: true,
      dedupe: importee => importee === 'svelte' || importee.startsWith('svelte/'),
    }),
    commonjs(),
    globals(),
    builtins(),

    // In dev mode, call `npm run start` once
    // the bundle has been generated
    !production && serve(),

    // Watch the `public` directory and refresh the
    // browser on changes when not in production
    !production && livereload('public'),

    // If we're building for production (npm run build
    // instead of npm run dev), minify
    production && terser(),
  ],
  watch: {
    clearScreen: false,
  },
}

function serve () {
  let started = false

  return {
    writeBundle () {
      if (!started) {
        started = true

        require('child_process').spawn('npm', ['run', 'start'], {
          stdio: ['ignore', 'inherit', 'inherit'],
          shell: true,
        })
      }
    },
  }
}
const sveltePreprocess = require('svelte-preprocess')

module.exports = {
  displayName: { name: 'web', color: 'magentaBright' },
  moduleFileExtensions: [
    'js',
    'json',
    'svelte',
  ],
  preset: 'rollup-jest',
  transform: {
    '\\.js$': 'rollup-jest',
    '\\.svelte$': ['jest-transform-svelte', { preprocess: sveltePreprocess(), debug: true }],
  },
  setupFilesAfterEnv: ['@testing-library/jest-dom/extend-expect'],
}
module.exports = {
  preset: 'jest-puppeteer', //ignore the preset part, I used for puppeteer
  transform: {
    '^.+\\.js?$': require.resolve('babel-jest'),
    "^.+\\.ts?$": "ts-jest" // this part is only required if you have typescript project
  }
};
const svelteJestPreprocessor = require('./svelteJestPreprocessor')
const sveltePreprocess = require('svelte-preprocess')

module.exports = {
  moduleFileExtensions: [
    'js',
    'json',
    'svelte',
  ],
  preset: 'rollup-jest',
  transform: {
    '\\.js$': 'rollup-jest',
    '\\.svelte$': ['jest-transform-svelte', {
      preprocess: [
        svelteJestPreprocessor(),
        sveltePreprocess(),
      ],
    }],
  },
  setupFilesAfterEnv: ['@testing-library/jest-dom/extend-expect'],
}
在使用之前,不要忘记安装babel jest、rollup插件babel等软件包。

自我回答:

最后,我编写了一个小预处理器,将
从'foo'导入foo
->
导入*替换为'foo'中的foo

SvelteTestPreprocessor.js

const svelteJestPreprocessor = () => ({
  // replace `import foo from 'foo'` -> `import * as foo from 'foo'`
  script: ({ content }) => ({
    // process each line of code
    code: content.split('\n').map(line =>
      // pass: no import, import with {}, import svelte component
      (!line.match(/\s*import/)) || (line.match(/{/)) || (line.match(/\.svelte/)) ? line
        : line.replace(/import/, 'import * as'),
    ).join('\n'),
  }),
})

module.exports = svelteJestPreprocessor
jest.config.js

import json from '@rollup/plugin-json'
import commonjs from 'rollup-plugin-commonjs'
import builtins from 'rollup-plugin-node-builtins'
import globals from 'rollup-plugin-node-globals'
import livereload from 'rollup-plugin-livereload'
import resolve from 'rollup-plugin-node-resolve'
import svelte from 'rollup-plugin-svelte'
import { terser } from 'rollup-plugin-terser'
import preprocess from 'svelte-preprocess'

const production = !process.env.ROLLUP_WATCH

export default {
  input: 'src/main.js',
  output: {
    sourcemap: true,
    format: 'iife',
    name: 'app',
    file: 'public/build/bundle.js',
  },
  plugins: [
    // https://github.com/rollup/plugins/tree/master/packages/json
    json(),

    svelte({
      // enable run-time checks when not in production
      dev: !production,
      // we'll extract any component CSS out into
      // a separate file — better for performance
      css: css => {
        css.write('public/build/bundle.css')
      },
      preprocess: preprocess(),
    }),

    // If you have external dependencies installed from
    // npm, you'll most likely need these plugins. In
    // some cases you'll need additional configuration —
    // consult the documentation for details:
    // https://github.com/rollup/rollup-plugin-commonjs
    resolve({
      browser: true,
      dedupe: importee => importee === 'svelte' || importee.startsWith('svelte/'),
    }),
    commonjs(),
    globals(),
    builtins(),

    // In dev mode, call `npm run start` once
    // the bundle has been generated
    !production && serve(),

    // Watch the `public` directory and refresh the
    // browser on changes when not in production
    !production && livereload('public'),

    // If we're building for production (npm run build
    // instead of npm run dev), minify
    production && terser(),
  ],
  watch: {
    clearScreen: false,
  },
}

function serve () {
  let started = false

  return {
    writeBundle () {
      if (!started) {
        started = true

        require('child_process').spawn('npm', ['run', 'start'], {
          stdio: ['ignore', 'inherit', 'inherit'],
          shell: true,
        })
      }
    },
  }
}
const sveltePreprocess = require('svelte-preprocess')

module.exports = {
  displayName: { name: 'web', color: 'magentaBright' },
  moduleFileExtensions: [
    'js',
    'json',
    'svelte',
  ],
  preset: 'rollup-jest',
  transform: {
    '\\.js$': 'rollup-jest',
    '\\.svelte$': ['jest-transform-svelte', { preprocess: sveltePreprocess(), debug: true }],
  },
  setupFilesAfterEnv: ['@testing-library/jest-dom/extend-expect'],
}
module.exports = {
  preset: 'jest-puppeteer', //ignore the preset part, I used for puppeteer
  transform: {
    '^.+\\.js?$': require.resolve('babel-jest'),
    "^.+\\.ts?$": "ts-jest" // this part is only required if you have typescript project
  }
};
const svelteJestPreprocessor = require('./svelteJestPreprocessor')
const sveltePreprocess = require('svelte-preprocess')

module.exports = {
  moduleFileExtensions: [
    'js',
    'json',
    'svelte',
  ],
  preset: 'rollup-jest',
  transform: {
    '\\.js$': 'rollup-jest',
    '\\.svelte$': ['jest-transform-svelte', {
      preprocess: [
        svelteJestPreprocessor(),
        sveltePreprocess(),
      ],
    }],
  },
  setupFilesAfterEnv: ['@testing-library/jest-dom/extend-expect'],
}

这是一个不需要的解决方法,但它目前仍然有效。

我也遇到了同样的问题。我还没有找到解决问题的办法,你的解决办法对我来说不管用,但我真的很高兴你花时间解决这个问题。非常感谢。我真的很感激你花时间给我一个详细的解释。我现在不想添加更多的编译器,但是你的方法对于已经在使用Babel的人来说真的很有用。也许我将来不得不接受你的方式。谢谢大家!@astanet如果你觉得这个答案有帮助,接受并投票表决,这样面对类似问题的人就会受益。