jest + enzyme单元测试

2019-10-27  本文已影响0人  kim_jin

安装

文件位置,以及目录写法

我们使用单元测试,一般的写法,是在待测试的方法或事组件的同级目录下,声明一个 __test__的文件夹,并在该文件夹下,命名一个以.test.js结尾的文件。

jest.config.js

module.exports = {
  collectCoverageFrom: ['src/**/*.{js,jsx,ts,tsx}', '!src/**/*.d.ts'],
  coverageDirectory: '<rootDir>/.tmp/coverage',
  coverageThreshold: {
    global: {
      branches: 80,
      functions: 80,
      lines: 80,
      statements: -10
    }
  },
  moduleNameMapper: {
    '^react-native$': 'react-native-web',
    '^.+\\.module\\.(css|sass|scss)$': 'identity-obj-proxy'
  }, // 代表需要被Mock的资源名称
  moduleFileExtensions: [
    'web.js',
    'js',
    'web.ts',
    'ts',
    'web.tsx',
    'tsx',
    'json',
    'web.jsx',
    'jsx',
    'node'
  ], // 代表支持加载的文件名
  resolver: 'jest-pnp-resolver',
  setupFiles: ['react-app-polyfill/jsdom'],
  // 配置`setupTests.js`中`enzyme`的连接,使得`enzyme`配置生效
  setupTestFrameworkScriptFile: '<rootDir>/src/setupTests.js',
  testMatch: [
    '<rootDir>/src/**/__tests__/**/*.{js,jsx,ts,tsx}',
    '<rootDir>/src/**/?(*.)(spec|test).{js,jsx,ts,tsx}'
  ], // 配置找到_test_下面的以Component.test.js,Component.spec.js
  testEnvironment: 'jsdom', // 测试环境
  testURL: 'http://localhost', // 它反映在诸如location.href之类的属性中
  transform: {
    '^.+\\.(js|jsx|ts|tsx)$': '<rootDir>/node_modules/babel-jest',
    '^.+\\.css$': '<rootDir>/config/jest/cssTransform.js',
    '^(?!.*\\.(js|jsx|ts|tsx|css|json)$)':
      '<rootDir>/config/jest/fileTransform.js'
  },
  transformIgnorePatterns: [
    '[/\\\\]node_modules[/\\\\].+\\.(js|jsx|ts|tsx)$',
    '^.+\\.module\\.(css|sass|scss)$'
  ],
  verbose: false
};

setUpTest.js

import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';

configure({ adapter: new Adapter() });

package.json的启动脚本配置

 "scripts": {
    "test": "node scripts/test.js",
  },

script下面test.js

'use strict';

// Do this as the first thing so that any code reading it knows the right env.
process.env.BABEL_ENV = 'test';
process.env.NODE_ENV = 'test';
process.env.PUBLIC_URL = '';

// Makes the script crash on unhandled rejections instead of silently
// ignoring them. In the future, promise rejections that are not handled will
// terminate the Node.js process with a non-zero exit code.
process.on('unhandledRejection', err => {
  throw err;
});

// Ensure environment variables are read.
require('../config/env');

const { execSync } = require('child_process');
const jest = require('jest');

const argv = process.argv.slice(2);

function isInGitRepository() {
  try {
    execSync('git rev-parse --is-inside-work-tree', { stdio: 'ignore' });

    return true;
  } catch (e) {
    return false;
  }
}

function isInMercurialRepository() {
  try {
    execSync('hg --cwd . root', { stdio: 'ignore' });

    return true;
  } catch (e) {
    return false;
  }
}

// Watch unless on CI, in coverage mode, or explicitly running all tests
if (!process.env.CI && argv.indexOf('--coverage') === -1 && argv.indexOf('--watchAll') === -1) {
  // https://github.com/facebook/create-react-app/issues/5210
  const hasSourceControl = isInGitRepository() || isInMercurialRepository();

  argv.push(hasSourceControl ? '--watch' : '--watchAll');
}

jest.run(argv);

enzyme
三种渲染方式
常见方法

编写测试用例

it

每个测试用例一个it函数代表,当然it还有一个别名,叫做test

我们先看一个例子:

// ,第一个参数描述它的预期行为
it('当我们传入的参数都是数字的时候', () = > {
  // 增加断言语句
})
describe

这个是一个测试的套件,在这个里面我们可以写多个it函数,这个的主要作用就是,我们有的时候,可能也需要对测试用例进行分类,这个时候,我们就用到了describe。我们看一下他的具体的写法

describe('这是一个小的逻辑单元', () => {
  it('当我们传入的参数都是数字的时候', () => {
  })

 it('当我们传入的参数都是英文的时候', () => {
  })
})

常见的断言

实战

对于方法的测试用例的编写

//bytesCount: 获取字符串长度,英文占一个字符,中文占两个字符
import { bytesCount } from '../bytesCount';

describe('测试计算字符串长度', () => {
  it('当传入的字符串为汉字', () => {
    expect(bytesCount('哈哈哈哈')).toBe(8);
  });
  it('当传入的字符串为数字', () => {
    expect(bytesCount(123)).toBe(3);
  });
  it('当传入的字符串为英文', () => {
    expect(bytesCount('abd')).toBe(3);
  });
  it('当传入的字符串为特殊字符', () => {
    expect(bytesCount('~|@%&*')).toBe(6);
  });

  it('当传入的字符串为null', () => {
    expect(bytesCount(null)).toBe(0);
  });
  it('当传入的字符串为undefined', () => {
    expect(bytesCount(undefined)).toBe(0);
  });

  it('当传入的字符串为数组', () => {
    expect(bytesCount([])).toBe(0);
  });
});

对于组件的测试用例的书写


//ArInput: 组件的作用,是用来在输入框中输入,当检测到,或是换行的时候,会在输入框下生成一个标签
import React from 'react';
import { mount, shallow } from 'enzyme';
import ArInput from '../index';

let wrapper;
const props = {
  max: 5,
  callback: jest.fn(),
  tagsChange: jest.fn(),
  placeholder: '非英文输入',
  tagsInit: [123, 333]
};

describe('Test MonthPicker Component', () => {
  beforeEach(() => {
    wrapper = mount(<ArInput {...props} />);
  });

  it('初始化生成的标签是否正常', () => {
    expect(wrapper.find('.ant-tag').length).toEqual(2);
  });

  it('placeHolder显示是否正常', () => {
    expect(wrapper.find('input').getDOMNode().placeholder).toEqual('非英文输入');
  });

  it('输入事件是否可以正确的使用', () => {
    const mockEvent = {
      target: {
        value: '13,'
      }
    };
    wrapper.find('input').simulate('keyup', mockEvent);
    expect(props.callback).toHaveBeenCalledWith('13,');
    expect(wrapper.state('tags').length).toEqual(3);
    expect(wrapper.state('tags')[2]).toEqual('13');
  });
});

踩过的坑

上一篇 下一篇

猜你喜欢

热点阅读