Jest + Vue - 语法错误:意外标记 <

Dan*_*ich 6 automated-tests typescript vue.js jestjs vuejs2

我正在尝试向使用 ts-Jest/Jest 和 Chai 用 TypeScript 编写的 Electron + Vue2 应用程序添加测试。但是,当我尝试运行我编写的简单测试以尝试确保 Jest 正常工作时,我现在遇到了 Jest 的问题,似乎不喜欢我正在导入我正在测试的组件模板这一事实可以在错误中看到。当我尝试搜索与此相关的内容时,我运气不佳,其中很多都指向“意外的令牌导入”,这是我已经解决的问题。

如果有人对我如何让测试不害怕导入 HTML 有任何见解或知识,那将是惊人的,因为我很难过,而且文档似乎没有指出任何有用的东西。

错误:

$ npm run test

> app@1.0.0 test C:\Users\daniel\Desktop\app\app
> jest --detectOpenHandles

FAIL src/app/features/app-window/app-window.component.spec.ts
  ? Test suite failed to run

    Jest encountered an unexpected token

    This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.

    By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".

    Here's what you can do:
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/en/configuration.html

    Details:

    C:\Users\daniel\Desktop\app\app\src\app\features\app-application-content\app-application-content.component.html:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){<webview-component v-if="src"
                                                                                             ^

    SyntaxError: Unexpected token <

      2 | import Component from 'vue-class-component'
      3 | import { Prop, Watch } from 'vue-property-decorator'
    > 4 | import Template from './app-application-content.component.html'
        | ^
      5 |
      6 | import * as qs from 'qs'
      7 | import { INameValue } from '../../../contracts/Core'

      at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:403:17)
      at Object.<anonymous> (src/app/features/app-application-content/app-application-content.component.ts:4:1)
      at Object.<anonymous> (src/app/features/app-content/app-content.component.ts:9:1)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        12.924s
Ran all test suites.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! app@1.0.0 test: `jest --detectOpenHandles`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the app@1.0.0 test script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\daniel\AppData\Roaming\npm-cache\_logs\2018-11-21T14_25_23_427Z-debug.log
Run Code Online (Sandbox Code Playgroud)

开玩笑的配置文件

module.exports = {
  preset: 'ts-jest/presets/js-with-ts',
  testEnvironment: 'node',
  verbose: true,
  moduleDirectories: ['node_modules', 'src'],
  modulePaths: ['<rootDir>/src', '<rootDir>/node_modules'],
  moduleFileExtensions: ['js', 'ts', 'json', 'node'],
  transformIgnorePatterns: ['node_modules/(?!(bootstrap-vue)/)'],
  testPathIgnorePatterns: [
    '/build/',
    '/config/',
    '/data/',
    '/dist/',
    '/node_modules/',
    '/test/',
    '/vendor/'
  ],
  globals: {
    'ts-jest': {
      tsConfig: './src/app/tsconfig.json'
    },
    NODE_ENV: 'test'
  }
}
Run Code Online (Sandbox Code Playgroud)

配置文件

{
  "compilerOptions": {
    "allowJs": true,
    "outDir": "./built/",
    "sourceMap": true,
    "strict": true,
    "moduleResolution": "node",
    "target": "ES2017",
    "experimentalDecorators": true,
    "noImplicitAny": false,
    "emitDecoratorMetadata": true,
    "allowSyntheticDefaultImports": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "esModuleInterop": true,
    "lib": ["es2017", "dom"],
    "include": [
      "**/*",
      "../types/**/*",
      "../../node_modules/bootstrap-vue/**/*",
      "../../node_modules/electron/**/*"
    ]
  }
}
Run Code Online (Sandbox Code Playgroud)

app-window.component.spec.ts

import { expect } from 'chai'
import 'jest'
import { appWindowComponent } from './app-window.component'

const appWindowComponent = new appWindowComponent()

describe('Test: Set Title Function', () => {
  it('should set the variable title to the passed variable', () => {
    const title = 'this is a test'
    appWindowComponent.setTitle(title)
    expect(appWindowComponent.title).to.equal(title)
  })
})
Run Code Online (Sandbox Code Playgroud)

Dan*_*ich 2

经过一番调查后,我在这里找到了答案

新的 jest.config.js

module.exports = {
  preset: 'ts-jest/presets/js-with-ts',
  testEnvironment: 'node',
  verbose: true,
  moduleDirectories: ['node_modules', 'src'],
  modulePaths: ['<rootDir>/src', '<rootDir>/node_modules'],
  moduleFileExtensions: ['js', 'ts', 'json', 'node', 'html'],
  transform: {
    '^.+\\.html$': '<rootDir>/config/htmlLoader.js'
  },
  transformIgnorePatterns: ['node_modules/(?!(bootstrap-vue)/)'],
  testPathIgnorePatterns: [
    '/build/',
    '/config/',
    '/data/',
    '/dist/',
    '/node_modules/',
    '/test/',
    '/vendor/'
  ],
  globals: {
    'ts-jest': {
      tsConfig: './src/app/tsconfig.json'
    },
    NODE_ENV: 'test'
  }
}
Run Code Online (Sandbox Code Playgroud)

笔记

transform: {
    '^.+\\.html$': '<rootDir>/config/htmlLoader.js'
  }, 

moduleFileExtensions: ['js', 'ts', 'json', 'node', 'html'],
Run Code Online (Sandbox Code Playgroud)

Html 加载器文件

const htmlLoader = require('html-loader')

module.exports = {
  process(src, filename, config, options) {
    return htmlLoader(src)
  }
}
Run Code Online (Sandbox Code Playgroud)

这似乎有效,因为我现在收到一个新错误:)