Skip to content

单元测试jest,react,enzyme,jsdom,clientWidth #1

@amandaXCY

Description

@amandaXCY

测试框架 jest

当你搜索jest时,你看到这么一句话:Jest · 令人愉快的JavaScript 测试(Delightful JavaScript Testing)
为什么这样说:
1.安装简单,只要npm install --save-dev jest 就可以开始写单元测试
2.自带了断言库,mock,测试报告,
3.还有一个非常棒的快照(Snapshot)

enzyme

它是react一个测试工具,可以不需要起动赖浏览器,来渲染react,它的api有点像jQuery api,使操作起来更方便。
enzyme分为三种渲染方式:

  • mount

    • 用于将React组件加载为真实DOM节点。
    • 可以实现 Full Rendering。比如说当我们需要对DOM API交互或者你需要测试组件的整个生命周期(如: componentDidMount)的时候,可以使用这个方法。需要注意的是,由于需要渲染成真实的dom节点,那么就需要测试环境对DOM API有支持。jest在内部使用了 jsdom 去模拟了DOM环境,所以我们就可以不用写一个setup.js文件去mock那些全局变量了
  • render

    方法将React组件渲染成静态的HTML字符串,然后分析这段HTML代码的结构,返回一个对象。它跟shallow方法非常像,主要的不同是采用了第三方HTML解析库Cheerio,它返回的是一个Cheerio实例对象。

  • shallow(渲染)

    将一个组件渲染成虚拟DOM对象,但是只渲染第一层,不渲染所有子组件,所以处理速度非常快。它不需要DOM环境,因为根本没有加载进DOM

一般我们常用的mount,和shallow

需要注意的是mount是依赖jsdom的

jsdom中有坑,请注意
jsdom模拟了浏览器的dom渲染,基本上也web api保持同步, ==但它有许多缺少的API==,
有两个功能不支持:

  • Navigation
`点击链接或导航或使用location.href去更改全局对象`
  • Layout

Layout不支持,不就不计算css可视化布局的元素的位置,比如:clientWidth、offsetTop、getBoundingClientRects(),innerText之类的属性,如果想测试这些可以mock,或者使用phantomJS、puppeteer之类的工具测试

  • ==innerText==
    先问大家一下,你们知道innerText和textContent的区别吗
  • innerText是被微软引进的,在早期的firefox和chrome都不支持
  • innerText是依赖布局渲染的,代码为证
<div id="t"><div>lions,
     tigers</div><div style="visibility:hidden">and bears</div></div>
     
 innerText输出:lions, tigers
 
 textContent输出:
 lions,
 tigersand bears
<div contenteditable>

A 

mind 

needs books<br>as a sword needs a whetstone<p>if it is to <span style="display: block">keep</span> its edge.
</p>
</div>
<div>
innerText<textarea id="innerText" style="display: inline-block"></textarea>
</div>
<div>
textContent<textarea id="textContent" style="display: inline-block"></textarea>
</div>
//css 
div, textarea {
display: inline-block;
vertical-align: top;
width: 250px;
height: 160px;
margin-right: 10px;
}

result

innerText

A mind needs books
as a sword needs a whetstone
if it is to
keep
its edge.
textContent

  
  A 
  
  mind 
  
  needs booksas a sword needs a whetstoneif it is to keep its edge.
  
  

innerText几乎精确地表示文本在页面上的显示方式,
textContent 忽略了span标签上的display:block

react 单元测试中遇到的坑

  • jsdom不支的部分的怎么测试,改代码吗,想过,可工程量太大,算了吧,当然你的组件如果没有使用ReactDOM,以下你可以跳过

document.body.innerHTML = '<div id="mounter" />';
wrapper = mount(commpent,{ attachTo: document.getElementById('mounter'))


wrapper.instance().node.getBoundingClientRect = jest.fn(() => {
      return {
        bottom: 100, height: 28, left: 0, right: 0, top: -50, width: 195,
      };
    });
    
Object.defineProperty(wrapper.instance().node, "innerText", {
    value: "1dddddddddddddddddddddddddddddddddddddd",
})
Object.defineProperty(wrapper.instance().node, "clientWidth", { value: 50 })
Object.defineProperty(wrapper.instance().node, "scrollWidth", { value: 100 })    

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions