javascript - 如何用 Jest 测试 JSX Vue 组件

标签 javascript vue.js jestjs jsx

我有以下组件(我简化了代码):

const Comp = Vue.component('Comp', {
    render (h) {
        // Other stuff ...
        return (<div>
            <div style={style}>
                <div style={{ display : 'inline-block' }} />
            </div>
        </div>)
    },
})

export default Comp

我写了下面的单元测试:

it('should be initialized', () => {
    const addEventListener = spyOn(document, 'addEventListener')

    const { vm } = shallowMount(Comp)

    expect(addEventListener).toHaveBeenCalledWith('dragend', jasmine.any(Function))
    expect(addEventListener).toHaveBeenCalledWith('keypress', jasmine.any(Function))
})

当我用 Jest 运行单元测试时,出现错误:

ReferenceError: dom is not defined

> 96 |         return (<div>
    |         ^
97 |             <div style={style}>
98 |                 <div style={{ display : 'inline-block' }} />
99 |             </div>

我的以下 babel.config.js 文件:

module.exports = (api) => {
    return {
        presets : ['@babel/preset-env', '@vue/babel-preset-jsx'],
        plugins : [
            '@babel/plugin-syntax-jsx',
            ['@babel/plugin-transform-react-jsx', { pragma : 'dom' }],
            [
                'module-resolver', {
                    root : ['./'],
                    alias : {
                        '@' : './src',
                        '~' : './examples',
                    },
                },
            ],
        ],
    }
}

还有我的 Jest 配置文件:

module.exports = {
    coverageReporters : ['html'],
    "transform": {
        "^.+\\.[t|j]sx?$": "babel-jest"
    },
    collectCoverageFrom : [
        "src/**/*.{js,jsx}"
    ],
    moduleNameMapper : {
        "\\.(css|less|sass|scss)$": "<rootDir>/tests/__mocks__/styleMock.js"
    },
    moduleFileExtensions : ['js', 'jsx']
}

当我使用 rollup 构建项目时,我没有错误,只是开 Jest 。

我错过了什么吗?

更新

我的 package.json 文件:

{
    "devDependencies": {
        "@babel/core": "^7.1.2",
        "@babel/plugin-syntax-jsx": "^7.0.0",
        "@babel/plugin-transform-react-jsx": "^7.0.0",
        "@babel/preset-env": "^7.1.0",
        "@rollup/plugin-alias": "^2.2.0",
        "@vue/babel-helper-vue-jsx-merge-props": "^1.0.0",
        "@vue/babel-preset-jsx": "^1.1.0",
        "@vue/test-utils": "^1.0.0-beta.31",
        "babel-core": "^7.0.0-bridge.0",
        "babel-helper-vue-jsx-merge-props": "^2.0.3",
        "babel-jest": "^23.6.0",
        "babel-loader": "^8.0.4",
        "babel-plugin-module-resolver": "^3.1.1",
        "babel-plugin-syntax-jsx": "^6.18.0",
        "babel-plugin-transform-vue-jsx": "^3.7.0",
        "babel-preset-env": "^1.7.0",
        "babel-preset-es2015": "^6.24.1",
        "codemirror": "^5.48.2",
        "css-loader": "^3.2.0",
        "docdash": "^1.0.3",
        "eslint": "6.1.0",
        "eslint-config-standard": "^12.0.0",
        "eslint-plugin-import": "^2.14.0",
        "eslint-plugin-jasmine": "^2.10.1",
        "eslint-plugin-node": "^8.0.0",
        "eslint-plugin-promise": "^4.0.1",
        "eslint-plugin-standard": "^4.0.0",
        "file-loader": "^4.2.0",
        "html-loader": "^0.5.5",
        "husky": "^3.0.8",
        "jest": "^23.6.0",
        "jquery": "^3.3.1",
        "js-beautify": "^1.10.0",
        "jsdoc": "^3.5.5",
        "jsx-render": "^1.1.1",
        "lint-staged": "^9.4.2",
        "node-sass": "^4.13.0",
        "rollup": "^1.26.4",
        "rollup-plugin-babel": "^4.3.3",
        "rollup-plugin-scss": "^1.0.2",
        "sass-loader": "^8.0.0",
        "style-loader": "^1.0.0",
        "url-loader": "^2.1.0",
        "vue": "^2.6.10",
        "vue-template-compiler": "^2.6.11",
        "vuex": "^3.1.1",
        "webpack": "^4.41.2",
        "webpack-cli": "^3.3.10",
        "webpack-dev-server": "^3.9.0"
    },
    "scripts": {
        "test": "jest",
        "build": "rollup -c"
    },
    "author": "",
    "license": "ISC",
    "husky": {
        "hooks": {
            "pre-push": "npm run test",
            "pre-commit": "lint-staged"
        }
    }
}

也许它会有用:我的项目不是用 vue-cli 创建的。我只将 Vue 用于两个组件。

最佳答案

你能试试下面的设置吗?

Package.json

{
  "name": "hello-world",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint",
    "test": "jest --watch"
  },
  "dependencies": {
    "core-js": "^3.4.4",
    "vue": "^2.6.10"
  },
  "devDependencies": {
    "@babel/plugin-transform-react-jsx": "^7.8.3",
    "@vue/cli-plugin-babel": "^4.1.0",
    "@vue/cli-plugin-eslint": "^4.1.0",
    "@vue/cli-service": "^4.1.0",
    "@vue/test-utils": "^1.0.0-beta.31",
    "babel-eslint": "^10.0.3",
    "babel-jest": "^25.1.0",
    "babel-plugin-module-resolver": "^4.0.0",
    "eslint": "^5.16.0",
    "eslint-plugin-vue": "^5.0.0",
    "jasmine": "^3.5.0",
    "jest": "^25.1.0",
    "vue-template-compiler": "^2.6.11"
  },
  "eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/essential",
      "eslint:recommended"
    ],
    "rules": {},
    "parserOptions": {
      "parser": "babel-eslint"
    }
  },
  "browserslist": [
    "> 1%",
    "last 2 versions"
  ],
  "jest": {
    "moduleFileExtensions": [
      "js",
      "json",
      "vue"
    ]
  }
}

组件

import Vue from "vue";

const Comp = Vue.component("Comp", {

  mounted() {
      document.addEventListener("click", () => {

      });

  },

  render(h) {
    // Other stuff ...
    return (
      <div>
        <div >Hello World!</div>
        <input type="text" id="someeid"></input>
        <div id="result"></div>
      </div>
    );
  }
});

export default Comp;

babel.config.js

module.exports = api => {
  api.cache(false);
  return {
    presets: ["@babel/preset-env", "@vue/babel-preset-jsx"],
    plugins: [
      "@babel/plugin-syntax-jsx",
      ["@babel/plugin-transform-react-jsx", { pragma : 'dom' }],
      [
        "module-resolver",
        {
          root: ["./"],
          alias: {
            "@": "./src",
            "~": "./examples"
          }
        }
      ]
    ]
  };
};

测试文件

import { shallowMount } from "@vue/test-utils";
import Comp from "./Comp";

it("should be initialized", () => {
  const addEventListener = spyOn(document, "addEventListener");
  const { vm } = shallowMount(Comp);
  expect(addEventListener).toHaveBeenCalledWith("click", , expect.any(Function));
});

codesandbox 示例

Edit How test JSX Vue component with Jest

关于javascript - 如何用 Jest 测试 JSX Vue 组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59802521/

相关文章:

javascript - 子元素不拉伸(stretch)固定高度的父容器

vue.js - 在 vuetify 数据表上导出到 excel

javascript - Vue 类与字符串绑定(bind)?

mongoose - 使用 Jests 和 Mongoose 测试 NestJS API 时出现 TypeError : updatedService. save 不是一个函数

javascript - Sails.JS - NTLM 身份验证失败时重试?

javascript - Web 应用程序翻译不适用于所有浏览器

javascript - 为什么 Vue 组件不会在选择更改时更新

reactjs - Jest-dom 给出错误 "TypeError: expect(...).toHaveStyle is not a function"

javascript - 为什么 JEST 测试中的 getCompulatedStyle() 返回与 Chrome/Firefox DevTools 中的计算样式不同的结果

javascript - 如何判断 DOM 元素在当前视口(viewport)中是否可见?