jest 实战总结

2,169 阅读3分钟

单元测试

单元测试是指的对软件中最小单元进行测试和验证。
我理解,单元测试一般是对于业务逻辑的测试,不论是业务逻辑组件还是 UI 库,校验的目的都是验证具体执行逻辑是否正确。

jest 测试

jest 单测需要 enzymejs.github.io/enzyme/ 配合完成,测试分为快照测试和 DOM 测试两种。

快照测试

快照测试会生成一份快照文件,后面的结果运行时都会和前面的结果进行比较。快照组件适合进行 UI 渲染的测试,防止渲染出现大变动,导致问题发生。

Dom测试

DOM 测试是将业务组件通过渲染运行,把得到的结果与预期进行比较发现问题,适合验证一些具体的业务逻辑。运行要点有:1 模拟用户测试环境,触发对应事件。2 监控对应输出数据是否符合要求。

jest 组件渲染方式

  1. shallow
    浅渲染,一层不涉及子组件,虚拟dom 渲染速度快。
  2. mount
    深渲染,涉及子组件,渲染速度慢。 一般来说能先用 shallow 就用 shallow,为了测试的性能考虑。

编码细节

事件触发

事件的触发分为三种:

  1. react 事件
    react 是自己维护事件机制管理的,它只会把事件绑定到具体的 document 节点上,然后自己进行处理,具体可以看看 zhuanlan.zhihu.com/p/25883536。 那么如何触发呢?触发react节点相关事件就需要Enzyme的simulate函数具体例子如下:
// 1 组件
 <input
    value={value}
    onChange={handleChange}
  />
 // 2 组件内部
  const { onChange } = this.props; 
  const handleChange = (e: Event) => {
    const val = e.target.value;
    setValue(val);
    if (onChange) {
      onChange(e, val);
    }
  };

 // 3 测试代码
 it('fires onChange event', () => {
    const handleChange = jest.fn();
    const wrapper = mount(<Input onChange={handleChange} />);
    wrapper.find('input').simulate('change', { target: { value: 'test' } });
    expect(handleChange).toBeCalled();
    expect(wrapper.find('input').props().value).toEqual('test');
  });
  1. dom事件

    假设业务中遇到了真实的dom绑定了某个事件,那么你需要利用浏览器的 EventTarget.dispatchEvent 方式进行触发,具体示例如下:

test('测试 dom 事件', () => {
    const ele = ReactDOM.findDOMNode(
      wrapper.find('.xselect').instance(),
    );

    ele.dispatchEvent(new Event('click', { bubbles: true }));
    wrapper.unmount();
  });
  1. 普通事件 如果传入了普通事件,可以尝试直接获取事件然后调用。示例代码如下:
it('测试编辑表单函数', async () => {
    await act(async () => {
      const wrapper = mount(
        <FieldForm />,
      );
      const onChange =
        wrapper.find('FormFieldInput').prop('onChange') || noop;
      onChange({
        target: {
          value: '输入测试名称1',
        },
      });
    });
  });

如何处理请求

mock 请求,因为我们注重的是业务逻辑。这里 mock 的方法有三种(本质一样,都是替换,就是具体应用时替换的范围不同)

  1. 直接 mock 业务函数
  2. 直接通过 jest.spyOn() mock 公共函数统一解决
  3. 运用第三方工具包

遇到属性变化等如何进行触发

jest 如果遇到渲染属性在断言之后的问题可以使用 act 函数。因为 act 能确保两件事情,即在 act 的 scope 中。

any state updates will be executed
any enqueued effects will be executed
引自 github.com/threepointo…

覆盖率问题

不要为了覆盖率而覆盖率,否则会对维护增添很多负担。比如下面的代码:

/* istanbul ignore next */
export const noop: () => void = () => {
  // do nothing.
};

其他问题

  1. 如果环境特殊有多个 react 实例? 直接改写 resolver 属性,将 react 指定一个版本的实例。具体直接参照链接代码即可,可以输出console观察具体属性。

www.jestjs.cn/docs/config…