我正在尝试将使用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"
]
}