Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
amandaXCY opened this issue Jan 25, 2018 · 0 comments
Open

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

amandaXCY opened this issue Jan 25, 2018 · 0 comments

Comments

@amandaXCY
Copy link
Owner

测试框架 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 })    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant