zoukankan      html  css  js  c++  java
  • React UI 组件库的 Jest 单元测试

    开始

    项目里安装 Jest

    yarn add --dev jest
    # or
    npm install --save-dev jest
    

    初始化配置文件

    在根目录下生成 jest.config.js 的配置文件,scripts里添加的jest命令会在 jest.config.js 里找配置

    npx jest --init 
    

    一些报错原因及处理

    不支持es模块的处理

    由于针对的是ui组件库进行测试不是纯函数测试,如果直接运行jest测试的话,会出现报错 SyntaxError: Cannot use import statement outside a module

    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:
         • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/en/ecmascript-modules for how to enable it. // 要支持 esmodule,还需要加babel插件
         • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config. // node_modules里有不需要转换的模块,需要载jest.config.js 配置文件里加transformIgnorePatterns来忽略
         • If you need a custom transformation specify a "transform" option in your config.  // jest.config.js 配置文件里添加transform来配置编译器
         • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option. //  如果需要支持css/less等,要在jest.config.js 配置文件里加transform 配置项
    
        You'll find more details and examples of these config options in the docs:
        https://jestjs.io/docs/en/configuration.html
    
        Details:
    
        ^^^^^^xxx
    
        SyntaxError: Cannot use import statement outside a module
    
    

    这是因为jest默认不支持es模块。

    官方支持ESM的配置 Native support for ES Modules

    查询官方文档中26.x版本关于ECMAScript Modules 的支持,对于这个特性的支持还是实验性的,目前bug也比较多,而且并未涉及到ts支持的介绍,如果是ts,需要使用ts-jest, 但是 ts-jest 的ESM 支持只有v27++版本可用,所以,如果用的是ts,是不能够使用 --experimental-vm-modules 特性的。

    27.x-next版本ECMAScript Modules介绍里有支持ts,配合ts-jest的27.x-next版本使用,新增了extensionsToTreatAsEsm配置项
    ts-jest 的 ESM Support配置文档

    如果使用27.x 还需要注意本地node版本限制 jest@27.0.0-next.4: The engine "node" is incompatible with this module. Expected version "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0". Got "14.13.1"

    25.x 版本及以前的不支持 esm 需要使用babel处理es模块

    // babel.config.js
    module.exports = {
      env: {
        test: { // 环境变量为test下的配置
          presets: ['@babel/preset-react', ['@babel/preset-env', { targets: {node: "current"}}],'@babel/preset-typescript'],
          plugins: [
            ['import', { libraryName: 'antd', libraryDirectory: 'es', style: true }],
            ['@babel/plugin-transform-runtime'],
            ['@babel/plugin-transform-modules-commonjs'] // jest不支持es模块,用babel处理
         ],
        }
     }
    }
    

    另外如果 import './style.less' less文件报错的话,需要使用 identity-obj-proxy 转换

    yarn add identity-obj-proxy --dev
    

    jest.config.js

    module.exports = {
        testMatch: ['/__tests__/*.[jt]s?(x)'],  // __tests__目录下的 j(t)s(x) 测试文件
        moduleFileExtensions: ['js', 'jsx', 'ts', 'tsx', 'json'], 
        transform: {
            // 用 `ts-jest` 处理 `*.ts` 文件
            '.*\.(ts|tsx)$': 'ts-jest',
            // 用 `babel-jest` 处理 js
            '.*\.(js|jsx)$': 'babel-jest'
        },
        moduleNameMapper: { // 
          '^.+\.(css|less)$': 'identity-obj-proxy' // 使用 identity-obj-proxy mock CSS Modules
        },
        transformIgnorePatterns: ['<rootDir>/node_modules/(?!(enzyme))'], // transform编译忽略哪些文件
        collectCoverage: true, // 开启收集Coverage(测试覆盖范围)
        coverageDirectory: '<rootDir>/coverage/', // 指定生成的coverage目录
        coveragePathIgnorePatterns: ['<rootDir>/coverage/'] //该路径下的测试,忽略测试覆盖率
    }
    

    使用babel

    yarn add --dev babel-jest @babel/core @babel/preset-env
    
    // babel.config.js
    module.exports = {
      presets: [['@babel/preset-env', {targets: {node: 'current'}}]],
    };
    

    使用TypeScript

    yarn add --dev @babel/preset-typescript @types/jest
    
    // babel.config.js
    module.exports = {
      presets: [
        ['@babel/preset-env', {targets: {node: 'current'}}],
         '@babel/preset-typescript',
      ],
    };
    

    ts 配置报错

    const Foo = () => <div>foo</div>;
                      ^
    SyntaxError: Unexpected token '<'
    

    这里是因为 tsconfig.json 里的配置jsx配置
    jsx配置从preserve改成react或者react-jsx

    一个参考配置

    {
      "compilerOptions": {
        "baseUrl": "./",
        "target": "esnext",
        "moduleResolution": "node",
        "jsx": "react-jsx",
        "esModuleInterop": true,
        "experimentalDecorators": true,
        "strict": true,
        "forceConsistentCasingInFileNames": true,
        "noImplicitReturns": true,
        "suppressImplicitAnyIndexErrors": true,
        "declaration": true,
        "skipLibCheck": true
      },
      "exclude": ["node_modules/**"]
    }
    
  • 相关阅读:
    I/O工作机制
    Apache和Tomcat区别
    jenkins学习和使用
    小程序富文本转化插件
    一个正则表达式的用法
    contenteditable="true"让div可编辑
    JS实现品字布局
    扯扯小程序。
    (canvas)两小球碰撞后的速度问题研究
    canvas画多边形
  • 原文地址:https://www.cnblogs.com/leiting/p/14437989.html
Copyright © 2011-2022 走看看