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

Jest Mock

mock 异步方法

1

2

3

export const runCallback = callBack => {

  return callBack();

};

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

1

2

3

4

5

6

7

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 函数输出的结果

1

2

3

4

5

6

7

8

9

10

// mock函数返回123,results的value变为123

const fn = jest.fn(() => 123);

// 等价于

fn.mockReturnValue("123");

// 等价于

fn.mockImplementation(() => 123);

// 模拟返回一次函数结果

fn.mockReturnValueOnce("123");

// 等价于

fn.mockImplementationOnce(() => 123);

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

  • 导出我们的请求方法

1

2

3

4

5

// demo.js

import axios from "axios";

export function getData() {

  return axios.get("http://www.dell-lee.com/react/api/demo.json");

}

  • 同级目录下建一个 **mocks** 的文件夹,建立同名的文件,此文件就是模拟请求的文件

 

1

2

3

4

5

export function fetchData() {

  return Promise.resolve({

    success: true

  });

}

  • 测试用例部分:

1

2

3

4

5

6

7

8

9

10

11

12

13

// 模拟 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

1

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

Mock Timers

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

1

2

3

4

5

export default callback => {

  setTimeout(() => {

    callback();

  }, 3000);

};

测试:

1

2

3

4

5

6

7

import timer from "./timer";

test("测试 timer", done => {

  timer(() => {

    expect(1).toBe(1);

    done();

  });

});

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

  • 通过 jest.useFakeTimers() 使用 jest "自制的" 定时器
  • 执行 timer 函数之后,快进时间 3 秒 jest.advanceTimersByTime(3000),这个方法可以调用任意次,快进的时间会叠加
  • 这时候我们已经穿梭到了 3 秒后,expect 也能生效了!

1

2

3

4

5

6

7

8

9

10

11

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 类

1

2

3

4

export class Util {

  a() {}

  b() {}

}

在 useUtil.js 调用这个类

1

2

3

4

5

6

import { Util } from "./util";

export function useUtil() {

  let u = new Util();

  u.a();

  u.b();

}

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

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

1

2

3

4

5

6

7

8

9

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

1

2

3

4

5

6

7

export const generateConfig = () => {

  return {

    server: "https://localhost",

    port: 8080,

    domain: "localhost"

  };

};

测试用例部分:

1

2

3

4

5

import { generateConfig } from "./config";

test("测试 generateConfig", () => {

  // 保存会生成 __snapshots__ 目录,记住配置相关内容

  expect(generateConfig()).toMatchSnapshot();

});

 

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

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

 

按 s 先跳过此次测试用例

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

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

1

time: new Date()

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

1

2

3

4

5

test("测试 generateConfig", () => {

  expect(generateConfig()).toMatchSnapshot({

    time: expect.any(Date)

  });

});

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

1

2

3

4

test("测试 generateConfig", () => {

  // 需要安装prettier

  expect(generateConfig()).toMatchInlineSnapshot();

});

DOM 测试

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

dom.js

1

2

3

4

export function addDivToBody() {

  const div = document.createElement("div");

  document.body.appendChild(div);

}

测试:

1

2

3

4

5

6

import { addDivToBody } from "./timer";

test("测试 addDivToBody", () => {

  addDivToBody();

  addDivToBody();

  expect(document.body.querySelectorAll("div").length).toBe(2);

});

​现在我也找了很多测试的朋友,做了一个分享技术的交流群,共享了很多我们收集的技术文档和视频教程。
如果你不想再体验自学时找不到资源,没人解答问题,坚持几天便放弃的感受
可以加入我们一起交流。而且还有很多在自动化,性能,安全,测试开发等等方面有一定建树的技术大牛
分享他们的经验,还会分享很多直播讲座和技术沙龙
可以免费学习!划重点!开源的!!!
qq群号:485187702【暗号:csdn11】

最后感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走! 希望能帮助到你!【100%无套路免费领取】

  • 24
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值