如何配置通过Vue cli 3添加到应用程序的Jest?

时间:2019-10-04 17:43:33

标签: vue.js webpack jestjs babeljs vue-cli-3

我正在尝试将使用Jest进行的测试引入使用Vue的应用程序构建中。我跑了

vue add unit-jest

类似于testing single file components with Jest guide的建议,创建了以下简单测试文件(Paginator.spec.js与Paginator.vue位于同一文件夹中,即/src/components):

import { mount } from '@vue/test-utils'
import Paginator from "./Paginator.vue";

describe('Paginator', () => {
    it('is a Vue instance', () => {
        const wrapper = mount(Paginator);
        // const a = 2;
        expect(wrapper.isVueInstance()).toBeTruthy();
        // expect(a).toBe(2);
    })
});

最初,Jest本身找不到文件存在一些问题。后来我更改了jest.config.js

testMatch: [
  '**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)'
],

testMatch: [
  '**/*.spec.(js|ts)|**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)'
],

在发生一些奇怪的故障后,我找到了文件(git stash,确保应用程序正在运行,然后git stash pop并开始查找文件)。

但是我仍然有Jest无法识别import的问题。无论运行jest还是npm test(即vue-cli-service test:unit),我都会遇到以下错误。像这样的简单测试正常工作:

describe('tests of components', () => {
    it('work', () => {
        const a = 2;
        expect(a).toBe(2);
    })
});

但是问题开头显示的测试带来了

  

测试套件无法运行
  [...]

({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import { mount } from '@vue/test-utils'
                                                                                                ^
SyntaxError: Unexpected token {
  at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:403:17)

如果我将导入顺序切换为

import Paginator from "./Paginator.vue";
import { mount } from '@vue/test-utils'

我明白了

● Test suite failed to run

  C:\NNTC\medkiosk\src\components\Paginator.spec.js:1
  ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import Paginator from "./Paginator.vue";
                                                                                                  ^^^^^^^^^

  SyntaxError: Unexpected identifier

    at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:403:17)

(除了扩展如上所示的regexp之外,我没有以任何其他方式更改jest.config.js)

这是什么问题?看起来Jest无法将import识别为一种语言功能。这是webpack配置错误的问题吗?缺少某些加载程序?

  • 项目中没有Webpack配置文件,因为它是从vue cli启动的。有人声称实际的配置位于node_modules/@vue/cli-service/webpack.config.js中,并没有太大帮助:

    // this file is for cases where we need to access the
    // webpack config as a file when using CLI commands.
    
    let service = process.VUE_CLI_SERVICE
    
    if (!service || process.env.VUE_CLI_API_MODE) {
      const Service = require('./lib/Service')
      service = new Service(process.env.VUE_CLI_CONTEXT || process.cwd())
      service.init(process.env.VUE_CLI_MODE || process.env.NODE_ENV)
    }
    
    module.exports = service.resolveWebpackConfig()
    

    (resolveWebpackConfig似乎是this one

  • 据我所知,在vue.config.js中调整了内部webpack配置is done,但我不知道这是开始修改的初始配置,实际上也应该进行调整< / p>

  • 我尝试过npm i babel-jest(不确定vue cli是否已安装),将.babelrc{ "presets": ["latest"] }一起添加,类似于a similar problem的人确实,尝试将来自该线程的另一个人建议的部分添加到vue.config.js中:

    configureWebpack: {
        module: {
            rules: [
                {
                    loader: "babel-loader",
                    options: {
                        presets: ["latest"]
                    }
                }
            ]
        }
    },
    

    还有here的一些建议,目前我没有主意

  • 在下面您可以看到所有配置文件

  • 一个好处:如果我将Paginator.spec.js重命名为Paginator.spec.ts,Jest会显示以下内容:

    ● Test suite failed to run
    
      Passing cached plugin instances is not supported in babel.loadPartialConfig()
    
        at forEach.item (node_modules/@babel/core/lib/config/partial.js:120:13)
            at Array.forEach (<anonymous>)
        at loadPartialConfig (node_modules/@babel/core/lib/config/partial.js:118:27)
        at TsJestTransformer.process (node_modules/ts-jest/dist/ts-jest-transformer.js:110:32)
    

有人可以建议如何修复配置吗?还是如何调试它?从目前为止我所读的内容来看,似乎Jest应该通过babel-loader获取一个通过管道传输的文件,但这似乎并非如此,但我不确定。我知道,我可能不太了解Webpack的工作原理,因此也欢迎学习一些提示,找到解决方案后,我会发布解决方案。

jest.config.js:

module.exports = {
  moduleFileExtensions: [
    'js',
    'jsx',
    'json',
    'vue',
    'ts',
    'tsx'
  ],
  transform: {
    '^.+\\.vue$': 'vue-jest',
    '.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub',
    '^.+\\.tsx?$': 'ts-jest'
  },
  transformIgnorePatterns: [
    '/node_modules/'
  ],
  moduleNameMapper: {
    '^@/(.*)$': '<rootDir>/src/$1'
  },
  snapshotSerializers: [
    'jest-serializer-vue'
  ],
  testMatch: [
    '**/*.spec.(js|ts)|**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)'
  ],
  testURL: 'http://localhost/',
  watchPlugins: [
    'jest-watch-typeahead/filename',
    'jest-watch-typeahead/testname'
  ],
  globals: {
    'ts-jest': {
      babelConfig: true
    }
  }
};

babel.config.js:

module.exports = {
  presets: [
    '@vue/app'
  ]
}

vue.config.js:

module.exports = {
    // the default value is '/', which may be ok for production but is not suitable for local build/deploy
    publicPath: ''
};

package.json的一部分:

  "scripts": {
    "lint": "vue-cli-service lint",
    "serve": "vue-cli-service serve",
    "test:unit": "vue-cli-service test:unit",
    "build": "vue-cli-service build"
  },
  "dependencies": {
    "core-js": "^2.6.5",
    "vue": "^2.6.10",
    "vuex": "^3.1.1",
    "vue-class-component": "^7.0.2",
    "vue-property-decorator": "^8.2.2",
    "axios": "^0.19.0",
    // more packages
  },
  "devDependencies": {
    "@types/jest": "^23.1.4",
    "@vue/cli-plugin-babel": "^3.11.0",
    "@vue/cli-plugin-eslint": "^3.11.0",
    "@vue/cli-plugin-typescript": "^3.11.0",
    "@vue/cli-plugin-unit-jest": "^3.11.0",
    "@vue/cli-service": "^3.11.0",
    "@vue/eslint-config-typescript": "^4.0.0",
    "@vue/test-utils": "1.0.0-beta.29",
    "babel-core": "7.0.0-bridge.0",
    "babel-eslint": "^10.0.1",
    "eslint": "^5.16.0",
    "eslint-plugin-vue": "^5.0.0",
    "ts-jest": "^23.0.0",
    "typescript": "^3.4.3",
    "vue-template-compiler": "^2.6.10"
  },
  "eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/essential",
      "eslint:recommended",
      "@vue/typescript"
    ],
    "rules": {},
    "parserOptions": {
      "parser": "@typescript-eslint/parser"
    },
    "overrides": [
      {
        "files": [
          "**/__tests__/*.{j,t}s?(x)"
        ],
        "env": {
          "jest": true
        }
      }
    ]
  },
  "postcss": {
    "plugins": {
      "autoprefixer": {}
    }
  },
  "browserslist": [
    "> 1%",
    "last 2 versions"
  ]
}

tsconfig.json:

{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "strict": true,
    "jsx": "preserve",
    "importHelpers": true,
    "moduleResolution": "node",
    "experimentalDecorators": true,
    "allowJs": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "sourceMap": true,
    "baseUrl": ".",
    "types": [
      "webpack-env",
      "jest"
    ],
    "paths": {
      "@/*": [
        "src/*"
      ]
    },
    "lib": [
      "esnext",
      "dom",
      "dom.iterable",
      "scripthost"
    ]
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.tsx",
    "src/**/*.vue",
    "tests/**/*.ts",
    "tests/**/*.tsx"
  ],
  "exclude": [
    "node_modules"
  ]
}

0 个答案:

没有答案