专栏首页腾讯移动品质中心TMQ的专栏Jest基本使用方法以及mock技巧介绍

Jest基本使用方法以及mock技巧介绍

导读

Jest是由Facebook开发并维护的一套js的单元测试框架,之前在后台的nodejs项目里面第一次尝试使用,感觉还是非常容易上手的,功能也比较强大。尤其是mock方面也别好用,还天然的支持覆盖率,所以非常推荐使用。

内置支持的功能如下:

  • 灵活的配置:比如,可以用文件名通配符来检测测试文件;
  • 测试的事前步骤(Setup)和事后步骤(Teardown),同时也包括测试范围;
  • 匹配表达式(Matchers):能使用期望expect句法来验证不同的内容;
  • 测试异步代码:支持承诺(promise)数据类型和异步等待async / await功能;
  • 模拟函数:可以修改或监查某个函数的行为;
  • 手动模拟:测试代码时可以忽略模块的依存关系;
  • 虚拟计时:帮助控制时间推移。

1  基本使用介绍

1.1  安装

1.2  一个简单的例子

被测试文件:sum.js

测试文件:  sum.test.js

将下面的配置部分添加到你的 package.json 里面:

  "scripts": {

    "test": "jest"

  }

执行下面的命令即可:

npm test

结果:

注意:jest会自动搜索路径下面所有test.js结尾的文件, 默认都会执行。

如果想单独运行某个测试文件可以直接加上文件名就可以。

如上面的例子可以:

npm test sum.test.js 或者jest sum.test.js

也可以在jest配置文件里配置上testRegex 

testRegex默认值:(/__tests__/.*|(\\.|/)(test|spec))\\.jsx?$

1.3  Jest配置选项

可以参考:

https://facebook.github.io/jest/docs/en/configuration.html里面,比较有用的就是collectCoverage 默认是false,设置成true的话执行完测试就会自动统计覆盖率。

如图:

1.4  jest命令行

除了用npm test 执行测试,也可以直接jest执行所有用例,jest支持的命令行参数可以参考:

https://facebook.github.io/jest/docs/zh-Hans/cli.html

命令行参数仅支持 jest 执行,npm test这样是不支持命令行的。

下面介绍比较常用的:

(1)——runInBand

jest --runInBand

可以顺序执行所有用例,默认所有用例是并行执行的。

(2)——debug

执行前打印jest所有配置信息。 

2  Jest的mock技巧介绍

2.1  基本的mock

2.1.1  Mock一个函数

方法的mock 非常简单,使用jest.fn 就可以非常简单的mock一个函数。

如下面的例子:代码里面有一个函数叫forEach。

此函数可以简单使用下面方法mock,并且jest提供一些方法可以确保查看mock函数被调用的情况:

mock属性的所有api可以参考:https://facebook.github.io/jest/docs/en/mock-function-api.html

2.1.2  Mock返回值

可以使用mock注入返回值,可以使用的api为mockReturnValue,mockReturnValueOnce等。

如下面的例子:

2.1.3  Mock内部实现

使用jest.fn或者mockImplementationOnce 可以完全替换需要mock的函数。

如下面的例子:

当需要mock的函数是从其他模块创建的就可以使用mockImplementation。

2.1.4  Mock名字

可以使用mockName 来给mock函数命名,如果没有命名,输出的日志默认就会打印jest.fn(),加上名字更有利于调试。

另外有用的mock方法可以参考:

https://facebook.github.io/jest/docs/en/mock-functions.html

2.2  模块的mock

这里面有几种方式来mock:

2.2.1  使用jest.mock自动mock

2.2.2  jest.mock()直接在单元测试里面mock 模块

例如我们很多产品代码里面会使用fs文件读取文件, 在单元测试中, 我们并不需要真去调用fs读取文件, 就可以考虑把fs模块mock掉, 如下代码:

2.2.3  在需要mock的模块目录临近建立目录__mocks__ 

这里面分两种情况:

2.2.3.1  对于用户目录下面的模块

例如我们需要mock目录models下面的user模块,那么我们就需要在models下面新建__mocks__目录(这里要区分大小写),然后新建文件user.js。

注意:用这种方式, 需要在单元测试文件中需添加下面的代码才能使此mock生效。

2.2.3.2  对于node_modules下面的模块

如果我们需要mock的模块是一个Node的模块(如lodash

),那么 __mocks__应该是挨着node_modules目录(除非你手动配置的 roots指向非本项目的root目录),这种就会自动mock了,也就是不需要在单元测试用例里再调用jest.mock('module_name')。

如果需要mock的模块是scoped模块,那么我们创建的mock的名字需要一致,例如, mock模块名字为 @scope/project-name,那么就需要创建__mocks__/@scope/project-name.js。

注意:如果我们需要mock node的核心模块(如fs或者path),那么还是需要显示的调用jest.mock('path') , 因为核心的node模块默然是不被mock的。

总结一下上面两种mock的目录应该如下:

2.3  类的mock

类可以用四种方式来mock一个类。

此部分我们使用下面的类来举例:

使用下列用例check下mock的执行情况:

2.3.1  jest.mock自动mock类所在的模块, 类和类的方法也自动被mock。

2.3.2  在_mock__路径建立mock的文件:

2.3.3  使用带模块工厂参数的mock。

形式如下jest.mock(path, moduleFactory),其中模板工厂参数指的是一个返回模块的函数

2.3.4.  使用mockImplementation()或者mockImplementationOnce()代替mock

可以使用mockImplementation() (or mockImplementationOnce())代替上面的带模板工厂参数的mock方法,mockImplementation或者mockImplementationOnce来修改mock。

如下面的例子,在使用了mock之后,随时可以使用。

可以参考:

https://facebook.github.io/jest/docs/en/es6-class-mocks.html

总结

对于简单的函数的mock,推荐使用jest.fn 来进行mock,针对不同的情况 (例如返回值或者替换实现),可以考虑使用mockReturnValue和mockImplementation;针对类和模块的mock,推荐使用自动的mock方法也就是jest.mock。对于比较复杂的类和接口,如果自动mock不能完成覆盖到的话,建议结合使用jest.mock和jest.fn().mockImplementation,或者可以使用jest.mock完全自己mock。

另外,jest里面有timer的mock,使用jest.useFakeTimers()可以自动mock代码里面的setTimeout和setInterval等函数具体信息请参考:

https://facebook.github.io/jest/docs/en/timer-mocks.html。

版权所属,禁止转载!!!

关注腾讯移动品质中心TMQ,获取更多测试干货!

本文分享自微信公众号 - 腾讯移动品质中心TMQ(gh_2052d3e8c27d)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-06-25

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • golang三大基础mock大法

    一、使用gomonkey来mock函数和方法  1、mock函数 gomonkey.ApplyFunc(target,double) 其中target是被mo...

    腾讯移动品质中心TMQ
  • Android终端单测杂烩

    给测试同学-关于语言补习  Kotlin *建议Java全熟之后再看,同时看有可能会记错用法; *语法比较多,需要慢慢消化; *优先看下官网的Higher-O...

    腾讯移动品质中心TMQ
  • 【穿山甲系列】找出后台偷偷耗电的元凶

    如图所示,在浏览器用户反馈中,耗电一直是头部问题之一,用户对于电量是非常敏感的,特别是那种类似“我明明就没用,怎么还在耗电?”的后台耗电问题,更容易引起用户的抱...

    腾讯移动品质中心TMQ
  • Python Mock模块原理及使用方法详解

    官方解释:Mock是Python中一个用于支持单元测试的库,它的主要功能是使用mock对象替代掉指定的Python对象,以达到模拟对象的行为

    砸漏
  • 使用yapi进行数据mock

    Ewall
  • 干货 | 携程酒店MOCK全链路实践

    Mock在整个软件开发测试周期中已经非常普遍,我们也会经常有意无意地使用它。譬如开发了一段代码,这段代码强依赖了其他服务,在对方服务完成之前,肯定是期望代码能够...

    携程技术
  • lazy-mock ,一个生成后端模拟数据的懒人工具

    最近发现一个比较好玩的东东,一个不需要 mock 并且匹配正则的接口直接转发到后端地址的小工具。

    业余草
  • 推荐一个生成后端模拟数据的懒人工具:lazy-mock

    来源 | https://juejin.im/post/6871592049485807630

    程序猿DD
  • golang单元测试之mock

    前面介绍了golang的一般单元测试,以及如何使用vscode进行高效的go单元测试开发。同时也说过一般单元测试重点在于cpu和内存类型的测试,而对io类型的测...

    黑光技术
  • React项目配置5(引入MockJs,实现假接口开发)

    本教程总共6篇,每日更新一篇,请关注我们!你可以进入历史消息查看以往文章,也敬请期待我们的新文章! 1、React项目配置1(如何管理项目公共js方法)---...

    前端人人

扫码关注云+社区

领取腾讯云代金券