React单元测试-Jest&enzyme

栏目: 编程工具 · 发布时间: 5年前

内容简介:复习一下 React 环境搭建。一个普通的 React、Redux 应用,效果如下
  • 结合一个 Todo-List 的例子进行 React 单元测试
  • 模板使用:React、Redux、Webpack@4、Babel@7

项目地址

https://github.com/ringcrl/react-todolist-enzyme

环境搭建

复习一下 React 环境搭建。

相关文档

依赖安装

# react
yarn add react react-dom react-redux redux

# babel
yarn add -D @babel/cli @babel/core @babel/polyfill @babel/preset-env @babel/preset-react babel-jest babel-loader

# webpack
yarn add -D webpack webpack-cli webpack-dev-server

# scss
yarn add -D node-sass sass-loader style-loader css-loader

# 测试套件
yarn add -D jest enzyme enzyme-adapter-react-16

环境配置

babel.config.js

const presets = [
  [
    '@babel/env',
    {
      targets: {
        edge: '17',
        firefox: '60',
        chrome: '67',
        safari: '11.1'
      }
    }
  ],
  ['@babel/preset-react']
];

module.exports = { presets };

jest.config.js

module.exports = {
  verbose: true,
  modulePaths: ['<rootDir>/__test__/'],
  moduleNameMapper: {
    '.(css|less)$': '<rootDir>/__test__/NullModule.js'
  },
  setupFilesAfterEnv: ['<rootDir>/__test__/setupTests.js'],
  transform: {
    '^.+\\.jsx?$': 'babel-jest'
  }
};

webpack.config.js

const webpack = require('webpack');
const env = process.env.NODE_ENV;
const path = require('path');

module.exports = {
  mode: 'development',
  devtool: 'eval',
  entry: ['./src/index.jsx'],
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js',
    publicPath: '/dist'
  },
  module: {
    rules: [
      {
        test: /\.js|jsx$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader'
        }
      },
      {
        test: /\.scss$/,
        use: [
          {
            loader: 'style-loader' // 将 JS 字符串生成为 style 节点
          },
          {
            loader: 'css-loader' // 将 CSS 转化成 CommonJS 模块
          },
          {
            loader: 'sass-loader' // 将 Sass 编译成 CSS
          }
        ]
      }
    ]
  },
  resolve: {
    extensions: ['.jsx', '.js']
  },
  plugins: [
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify(env)
    })
  ]
};

.eslintrc.js

module.exports = {
  "parser": "babel-eslint",
  "parserOptions": {
      "ecmaVersion": 6,
      "sourceType": "module",
      "ecmaFeatures": {
          "jsx": true,
          "modules": true,
          "experimentalObjectRestSpread": true
      }
  },
  "env": {
    "browser": true,
    "commonjs": true,
    "es6": true,
    "node": true,
    "jest": true,
  },
  "globals": {
    "Raven": true, // 文件中注释 /* global Raven */
  },
  "extends": [
    "eslint:recommended", // https://cn.eslint.org/docs/rules/
    "plugin:react/recommended" // https://github.com/yannickcr/eslint-plugin-react
  ], 
  "parserOptions": {
    "ecmaVersion": 2018,
    "sourceType": "module"
  },
  "rules": {
    "prefer-const": ["error"],
    "no-var": ["error"],
    "linebreak-style": ["error", "unix"],
    "quotes": ["error", "single"],
    "semi": ["error", "always"],
    "no-control-regex": ["off"],
    "no-useless-escape": ["off"],
    "no-console": ["off"],
    "react/prop-types": ["off"],
  }
};

.editorconfig

[*]
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = false
insert_final_newline = true
indent_style = space
indent_size = 2

[{*.yml,*.json}]
indent_style = space
indent_size = 2

Todo list

src
├── actions
│   └── index.js
├── components
│   ├── todo-creator
│   │   └── index.jsx
│   └── todo-item
│       └── index.jsx
├── constants
│   └── index.js
├── container
│   ├── index.jsx
│   └── index.scss
├── index.jsx
└── reducers
    ├── index.js
    └── todos.js

一个普通的 React、Redux 应用,效果如下

React单元测试-Jest&enzyme

  • 回车后添加 Todo Item
  • 点击 Todo Item 前面的 Input 删除此 Item

__test__

文件概述

__test__
├── NullModule.js
├── components
│   ├── todo-creator
│   │   └── index.test.js
│   └── todo-item
│       └── index.test.js
├── reducers
│   └── todos.test.js
└── setupTests.js
  • NullModule.js 导出的是空对象,用于跳过样式文件的检测,与 jest.config.js 里面的 moduleNameMapper 字段对应
  • setupTests.js 用于使用 Jest 配置 Enzyme 和适配器, 文档

测试内容

  • TodoCreator(输入框)
    • 正确渲染了 render input 输入框
    • 如果输入框有输入内容,回车后 addTodo reducer 被调用
    • 如果输入框没有输入内容,回车后 addTodo reducer 不被调用
    • addTodo 之后清空输入框
  • TodoItem
    • Todo item 被正确渲染
    • input 改变时删除 item
    • 渲染 item 的 title
  • reducers
    • 初始 state 正确
    • ADD_TODO 结果正确
    • DELETE_TODO 结果正确

具体逻辑看 __tests__ 部分代码,主要使用了 enzyme 的类 JQ API,进行 "DOM" 检测、事件触发等操作。

expect(wrapper.find('input').length).toBe(1)

wrapper.find('input').simulate('change');

expect(wrapper.find('.todo-title').text()).toBe(props.todo.text);

const mockEventObj = {
  key: 'Enter',
  target: {
    value: 'TEST'
  }
};
wrapper.find('input').simulate('keydown', mockEventObj);
expect(props.addTodo).toBeCalled();

// ...

测试结果

React单元测试-Jest&enzyme


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

JavaScript王者归来

JavaScript王者归来

月影 / 清华大学出版社 / 2008-7 / 86.00元

你手中的这本《JavaScript王者归来》不仅是一本传播知识的书,更是一本求道的书。 本书分为五个部分循序渐进地与读者讨论了JavaScript的方方面面,从简单的语言基础到丰富的实际应用再到深入剖析语言本质的高级话题,字里行间包含着作者多年工作中对JavaScript实践乃至程序设计思想的深入思考和总结。 本书揭开了JavaScript的面纱,绕过误解和虚幻的表象,引领你探索程序王......一起来看看 《JavaScript王者归来》 这本书的介绍吧!

URL 编码/解码
URL 编码/解码

URL 编码/解码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具