【问题标题】:How to use Jest with React and Webpack如何在 React 和 Webpack 中使用 Jest
【发布时间】:2017-03-30 09:36:05
【问题描述】:

我试图将 Jest 配置为与 React 和 Webpack 一起使用。由于我使用 Webpack 别名和 ES6 模块导出的方式,我在配置它时遇到了很大的问题。

由于没有其他问题对我有用,我想向您展示我做了什么才能将 Jest 与 ReactJs 和 Webpack 一起使用。

【问题讨论】:

    标签: facebook reactjs webpack ecmascript-6 jestjs


    【解决方案1】:

    我的主要问题是我使用 ES6 导出我的模块,我需要一个预处理器来处理导入。

    鉴于该基本组件:

    import 'Incription.scss';
    
    import React from 'react;
    import InscriptionModal from './InscriptionModal';
    
    class Inscription extends React.Component {
        constructor(props) {
            super(props)
        }
        render() {
            return <InscriptionModal />;
        }
    }
    
    export default Inscription;
    

    测试如下:

    import React from 'react';
    import renderer from 'react-test-renderer';
    
    import Inscription from './Inscription';
    
    describe('Inscription', () => {
        it('renders correctly', () => {
            const tree = renderer.create(<Inscription />).toJSON();
    
            expect(tree).toMatchSnapshot();
        });
    });
    

    package.json 中没有配置,当我运行测试时,我总是以:

    SyntaxError: Unexpected token .
    

    基本上,我需要处理资产文件,为此,我需要使用 moduleNameMapper 更改我的 package.json jest 配置。:

    "jest": {
        "moduleNameMapper": {
          "^.+\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/cfg/mocks/fileMock.js",
          "^.+\\.(css|scss)$": "<rootDir>/cfg/mocks/styleMock.js"
        }
    }
    

    fileMock.js

    module.exports = 'test-file-stub';
    

    styleMock.js

    module.exports = {};
    

    下一个问题是 Jest 无法处理 ES6 的模块,所以我需要一个预处理器。确切的错误是:

    Cannot find module './InscriptionModal' from 'Inscription.spec.js'
    

    我发现了一个名为 jest-webpack-alias 的插件,它正在这样做,我再次更改了我的 package.json 的开玩笑配置:

    "jest": {
        ...
        "transform": {
            "^.+\\.js$": "<rootDir>/cfg/preprocessor.js"
        },
        "jest-webpack-alias": {
            "configFile": "cfg/jest.js"
        },
    }
    

    我的 preprocessor.js 文件看起来像:

    const babelJest = require('babel-jest');
    
    require('babel-register');
    const webpackAlias = require('jest-webpack-alias');
    
    module.exports = {
      process: function (src, filename) {
        if (filename.indexOf('node_modules') === -1) {
          src = babelJest.process(src, filename);
          src = webpackAlias.process(src, filename);
        }
        return src;
      }
    };
    

    注意我的 package.json 中 jest-webpack-file 的 configFile。它有我的 webpack 测试配置的路线。该文件如下所示:

    'use strict';
    
    const path = require('path');
    
    const srcPath = path.join(__dirname, '/../src/');
    const baseConfig = require('./base');
    
    module.exports = {
      devtool: 'eval',
      module: {
        loaders: [{
          test: /\.(png|jpg|gif|woff|woff2|css|sass|scss|less|styl)$/,
          loader: 'null-loader'
        }, {
          test: /\.(js|jsx)$/,
          loader: 'babel-loader',
          include: [].concat(
            baseConfig.additionalPaths,
            [
              path.join(__dirname, '/../src'),
              path.join(__dirname, '/../test')
            ]
          )
        }, {
          test: /\.json$/,
          loader: 'json-loader'
        }]
      },
      resolve: {
        root: path.resolve(__dirname, '/../src'),
        extensions: [
          '',
          '.js',
          '.jsx'
        ],
        alias: {
          actions: `${srcPath}/actions/`,
          components: `${srcPath}/components/`,
          sources: `${srcPath}/sources/`,
          stores: `${srcPath}/stores/`,
          services: `${srcPath}/services/`,
          styles: `${srcPath}/styles/`,
          i18n: `${srcPath}/i18n/`,
          config: `${srcPath}/config/test`,
          utils: `${srcPath}/utils/`,
          vendor: `${srcPath}/vendor/`,
          images: `${srcPath}/images/`
        }
      }
    };
    

    在此文件中添加项目的根目录非常重要,因为如果不添加,您将遇到此错误:

    Missing setting "resolve.modules" (webpack v2) or "resolve.root" (webpack v1) in...
    

    添加配置后,您现在可以使用 Jest mock 模拟您的导入:

    jest.mock('./InscriptionModal, () => {
      return {};
    });
    

    在运行测试时添加参数--no-cache 很重要,因为 Jest 会缓存转换后的模块文件以加快测试执行速度。

    另一个烦人的错误是当您尝试在测试中添加enzymeReact Test Utils 时。它打印此错误:

    Invariant Violation: ReactCompositeComponent: injectEnvironment() can only be called once.
    

    have to do 是在你的测试中添加这行代码:

    jest.mock('react/lib/ReactDefaultInjection');
    

    希望对你有用!

    更新

    UpgradingReact 和 React-dom 到 v15.4.0 修复了最新的错误评论。

    【讨论】:

      猜你喜欢
      • 2015-05-06
      • 2017-12-02
      • 2017-11-10
      • 2017-02-22
      • 2018-06-29
      • 1970-01-01
      • 2020-10-12
      • 2018-10-31
      • 1970-01-01
      相关资源
      最近更新 更多