前端自动化测试之Jest 进阶教程示例

 更新时间:2023年02月14日 10:38:56   作者:云牧  
这篇文章主要为大家介绍了前端自动化测试之Jest 进阶教程示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

Jest Mock

mock 异步方法

export const runCallback = callBack => {
  return callBack();
};

我们对上面的代码进行测试:

import { runCallback } from "./demo";
test("测试 runCallback", () => {
  const fn = jest.fn(); // mock函数,捕获函数的调用
  runCallback(fn);
  expect(fn).toBeCalled();
  // expect(runCallback(() => "hello")).toBe("hello");
});

通过 jest.fn 生成的 mock 函数,我们可以打印其 fn.mock,得到以下结果:

  • calls 被调用的情况,通过 fn.mock.calls.length 可获取 mock 函数被调用次数,每个数组里存放传递给 mock 函数的参数
  • instances jest.fn 生成函数的 this 指向
  • invocationCallOrder 传递进去函数的执行顺序
  • results 函数输出的结果
// mock函数返回123,results的value变为123
const fn = jest.fn(() => 123); 
// 等价于
fn.mockReturnValue("123");
// 等价于
fn.mockImplementation(() => 123);
// 模拟返回一次函数结果
fn.mockReturnValueOnce("123");
// 等价于
fn.mockImplementationOnce(() => 123);

测试异步代码每次都发送真实请求,无疑是很慢的,我们可以使用 mock 模拟请求方法

  • 导出我们的请求方法
// demo.js
import axios from "axios";
export function getData() {
  return axios.get("http://www.dell-lee.com/react/api/demo.json");
}
  • 同级目录下建一个 **mocks** 的文件夹,建立同名的文件,此文件就是模拟请求的文件

export function fetchData() {
  return Promise.resolve({
    success: true
  });
}
  • 测试用例部分:
// 模拟 request 模块
jest.mock("./request.js"); // 也可以在 jest.config.js 里面手动设置 automock 为 true
// 取消 mock
// jest.unmock("./demo.js");
import { fetchData } from "./request";
test("测试 fetchData", () => {
  // 此请求实际会请求 __mocks__ 下的 request.js 方法
  return fetchData().then(data => {
    expect(data).toEqual({
      success: true
    });
  });
});

如果我们 request.js 某些方法不需要 mock

const { getNumber } = jest.requireActual("./request.js");

Mock Timers

当我们有如下代码需要测试的时候:

export default callback => {
  setTimeout(() => {
    callback();
  }, 3000);
};

测试:

import timer from "./timer";
test("测试 timer", done => {
  timer(() => {
    expect(1).toBe(1);
    done();
  });
});

我们不可能总是等待定时器完才去执行用例,这时候我们要用 Jest 来操作时间!步骤如下:

  • 通过 jest.useFakeTimers() 使用 jest "自制的" 定时器
  • 执行 timer 函数之后,快进时间 3 秒 jest.advanceTimersByTime(3000),这个方法可以调用任意次,快进的时间会叠加
  • 这时候我们已经穿梭到了 3 秒后,expect 也能生效了!
import timer from "./timer";
beforeEach(() => {
  jest.useFakeTimers();
});
test("测试 timer", () => {
  // jest.fn() 生成的是一个函数,这个函数能被监听调用过几次
  const fn = jest.fn();
  timer(fn);
  jest.advanceTimersByTime(3000);
  expect(fn).toHaveBeenCalledTimes(1);
});

Mock 类

  • 当我们只关注类的方法是否被调用,而不关心方法调用产生的结果时,可以 mock 类

util.js 中定义了 Util

export class Util {
  a() {}
  b() {}
}

useUtil.js 调用这个类

import { Util } from "./util";
export function useUtil() {
  let u = new Util();
  u.a();
  u.b();
}

我们需要测试 u.au.b 被调用

jest.mock("util.js") 会将 Util、Util.a、Util.b 都 mock 成 jest.fn

jest.mock("util.js"); // mock Util 类
import { Util } from "./util/util";
import { useUtil } from "./util/uesUtil";
test("util 的实例方法被执行了", () => {
  useUtil();
  expect(Util).toHaveBeenCalled();
  expect(Util.mock.instances[0].a).toHaveBeenCalled();
  expect(Util.mock.instances[0].b).toHaveBeenCalled();
});

Snapshot 快照测试

  • 将文件内容拍照一样拍下来。下次运行测试用例的时候,如果内容变化,则会报错

config.js

export const generateConfig = () => {
  return {
    server: "https://localhost",
    port: 8080,
    domain: "localhost"
  };
};

测试用例部分:

import { generateConfig } from "./config";
test("测试 generateConfig", () => {
  // 保存会生成 __snapshots__ 目录,记住配置相关内容
  expect(generateConfig()).toMatchSnapshot();
});

改变 config 文件内容,测试不通过,按 u 可以更新快照

如果有两个快照改变,我们需要一个个更新,我们可以按 i进入以下界面:

s 先跳过此次测试用例

u 可一个个更新快照内容,使得测试通过

如果我们配置有不断变化的量:

time: new Date()

我们可以这样测试,保证 time 是一个 Date 类型即可

test("测试 generateConfig", () => {
  expect(generateConfig()).toMatchSnapshot({
    time: expect.any(Date)
  });
});

我们除了可以成目录保存快照内容,还可以生成行内快照,存放本文件即可

test("测试 generateConfig", () => {
  // 需要安装prettier
  expect(generateConfig()).toMatchInlineSnapshot();
});

DOM 测试

  • jest 自己模拟了一套 jsDom api ,所以我们能使用 jest 测试 dom

dom.js

export function addDivToBody() {
  const div = document.createElement("div");
  document.body.appendChild(div);
}

测试:

import { addDivToBody } from "./timer";
test("测试 addDivToBody", () => {
  addDivToBody();
  addDivToBody();
  expect(document.body.querySelectorAll("div").length).toBe(2);
});

以上就是前端自动化测试之Jest 进阶教程示例的详细内容,更多关于Jest 前端自动化测试的资料请关注脚本之家其它相关文章!

相关文章

  • JavaScript Promise实现异步并发任务控制器

    JavaScript Promise实现异步并发任务控制器

    这篇文章主要为大家介绍了JavaScript Promise实现异步并发任务控制器示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-06-06
  • 前端面试必会网络跨域问题解决方法

    前端面试必会网络跨域问题解决方法

    这篇文章主要为大家介绍了前端面试必会的网络跨域问题解决方法讲解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07
  • JS前端设计模式之发布订阅模式详解

    JS前端设计模式之发布订阅模式详解

    这篇文章主要为大家介绍了JS前端设计模式之发布订阅模式详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • 微信小程序 chooseImage选择图片或者拍照

    微信小程序 chooseImage选择图片或者拍照

    这篇文章主要介绍了微信小程序 chooseImage选择图片或者拍照的相关资料,需要的朋友可以参考下
    2017-04-04
  • ECharts transform数据转换和dataZoom在项目中使用

    ECharts transform数据转换和dataZoom在项目中使用

    这篇文章主要为大家介绍了ECharts transform数据转换和dataZoom在项目中使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • 详解requestAnimationFrame和setInterval该如何选择

    详解requestAnimationFrame和setInterval该如何选择

    这篇文章主要为大家介绍了requestAnimationFrame和setInterval该如何选择示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪<BR>
    2023-03-03
  • 特殊字符、常规符号及其代码对照表

    特殊字符、常规符号及其代码对照表

    特殊字符、常规符号及其代码对照表...
    2006-06-06
  • 微信小程序 navbar实例详解

    微信小程序 navbar实例详解

    这篇文章主要介绍了微信小程序 navbar实例详解的相关资料,需要的朋友可以参考下
    2017-05-05
  • js 数组 fill() 填充方法

    js 数组 fill() 填充方法

    这篇文章主要介绍了js 数组 fill() 的填充方法,初始化数组的方法,但是初始化数组之后,数组中的每一项元素默认为 empty 空位占位,如何对数组这些空位添加默认的元素,ES6提供了 fill() 方法实现这一操作。本文总结数组 fill() 方法的详细使用,需要的朋友可以参考一下
    2021-10-10
  • js作用域及作用域链工作引擎

    js作用域及作用域链工作引擎

    这篇文章主要为大家介绍了js作用域及作用域链工作引擎,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07

最新评论