使用Jest进行React单元测试

发表于:2023-5-24 09:34

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:正是江南好时节    来源:稀土掘金

  1.单元测试的定义
  测试根据不同的维度有多种分类方式,按照测试阶段主要有单元测试、集成测试和系统测试。单元测试(Unit Tesing)是针对程序的最小单位,对代码进行正确性检验的一种测试手段。在过程化编程中,最小单元是单个程序、函数、过程等;对于面向对象编程,最小单元是对象方法,包括基类(超类)、抽象类、或者派生类(子类)中的方法。
  2.单元测试的意义
  提升效率:通过 mock 数据,及早发现问题,而越早发现Bug,造成的浪费就会越小
  结构设计:单元测试可以充当一个设计工具,有助于开发人员去思考代码结构的设计,让代码更加有利于测试。特别是先写测试,迫使我们把程序设计成易于调用和可测试的,即迫使我们解除软件中的耦合。
  3.安装与配置
  下文介绍使用 Jest 对 React 程序进行单元测试,采用React Testing Library 作为测试工具库。
  安装Jest
  yarn add --dev jest
  yarn add --dev jest-environment-jsdom jest-less-loader 
  yarn add @testing-library/jest-dom @testing-library/react
  配置Jest
  jest --init
  √ Would you like to use Jest when running "test" script in "package.json"? … yes
  √ Would you like to use Typescript for the configuration file? … no
  √ Choose the test environment that will be used for testing ? jsdom (browser-like)
  √ Do you want Jest to add coverage reports? … yes
  √ Which provider should be used to instrument code for coverage? ? babel
  √ Automatically clear mock calls and instances between every test? … no
  配置 Babel
  yarn add --dev babel-jest @babel/core @babel/preset-env @babel/preset-react
  在项目的根目录下创建?babel.config.js?,通过配置 Babel 使其能够兼容当前的 Node 版本。
  module.exports = {
    presets: [
      ['@babel/preset-env', {targets: {node: 'current'}}],
      '@babel/preset-react'
    ],
  };
  在package.json中配置如下内容:
  "scripts": {
      "test": "jest",
   },
  "resolutions": {
      "jest-environment-jsdom": "27.4.6"
   },
  在jest.config.js中配置如下内容:
  module.exports = {
    setupFilesAfterEnv: ['@testing-library/jest-dom'],
    testEnvironment: 'jsdom',
    clearMocks: true,
    coverageDirectory: "coverage",
    moduleDirectories: [
      "node_modules", "src"
    ],
    moduleNameMapper: {
      '^@/(.*)$': '<rootDir>/src/$1',
      '\\.(jpg|ico|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
        '<rootDir>/test/fileMock.js',
      '\\.(css|less)$': '<rootDir>/test/styleMock.js',
    },
    transform: {
      "^.+\\.(js|jsx)$": "babel-jest",
      '\\.(less|css)$': 'jest-less-loader'
    },
    transformIgnorePatterns: [
      '/node_modules/(?!antd|@ant-design|rc-.+?|@babel/runtime).+(js|jsx)$',
    ],
  }
  其中,fileMock.js与styleMock.js文件内容均为:
  module.exports = {}
  matchMedia.mock.js文件内容如下:
  Object.defineProperty(window, 'matchMedia', {
    writable: true,
    value: jest.fn().mockImplementation(query => ({
      matches: false,
      media: query,
      onchange: null,
      addListener: jest.fn(), // deprecated
      removeListener: jest.fn(), // deprecated
      addEventListener: jest.fn(),
      removeEventListener: jest.fn(),
      dispatchEvent: jest.fn(),
    })),
  });
  4.常见问题
  (1)Jest encountered an unexpected token
  解决方案:
   moduleNameMapper: {
      "^@/(.*)$": "<rootDir>/src/$1",
      '\\.(css|less)$': '<rootDir>/tests/styleMock.js',
      'antd/es/locale/zh_CN':'<rootDir>/tests/styleMock.js'
    },
  (2)无法读取 props.history.push
  解决方案:
   test('test', async () => {
      const mProps = { history: { push: jest.fn() } }   
      await render(
          <AppStore {...mProps} />
      )
      expect(mProps.history.push).toBeCalledWith('/app/shelve')
    })
  本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号