Enzyme测试React


2019-11-13 react

前言

对于新手来说,找到一个能上手的Enzyme测试React的教程不难,难的是应该怎么把 Enzyme提供的测试方法用起来。上手Enzyme的正确使用姿势应该是:

  • 围绕Enzyme画出自学提问图
  • 熟悉 Enzyme提供的测试方法 + demo预研

Enzyme 是什么

enzyme 是Airbnb推出一款用于测试React编写的组件的测试工具。通过它你可以轻松的完成断言,DOM操作以及遍历 React Components 输出。

安装

npm i --save-dev enzyme enzyme-adapter-react-16

Enzyme 有哪些测试方法

以下面的Todo应用为例

为上面的App组件设置3个测试点

  • 测试标题是否为 Todos
  • 测试Todo项的初始状态("未完成"或"已完成")
  • 测试删除按钮是否管用

shadow():当没有和DOM互动,不涉及子组件时(“表层感,一个字浅”)

describe('Enzyme Shadow',function () {  
  //测试组件标题是否为 Todos
  it('App/ ‘s title should be Todos',function(){    
    let app = render(<App/>);
    expect(app.find('h1').text()).to.equal('Todos');  
  });
});
1
2
3
4
5
6
7

其中穿插了Enzyme的find()方法:只支持简单选择器,稍微复杂的css都不支持

    类选择器:component.find(".player")
    id选择器:component.find("#player")
    标签选择器:component.find("h1")
    component.find('div.custom-class'); // by compound selector
    component.find(TableRow); // by constructor
    component.find('TableRow'); // by display name
1
2
3
4
5
6

上述App的标题就符合该情况,只是测试组件的标题名。所以用shadow()非常适合

render():它跟shallow方法非常像,主要的不同是采用了第三方HTML解析库Cheerio,它返回的是一个Cheerio实例对象

describe('Enzyme Render', function () {  
  //测试Todo项的初始状态("未完成"或"已完成")
  it('Todo item should not have todo-done class', function () {   
   let app = render(<App/>); 
   expect(app.find('.todo-done').length).to.equal(0);
 });
});
1
2
3
4
5
6
7

mount():将React组件加载为真实的DOM。“找到DOM节点,操作它”(”实在感“),完全渲染实际上将组件安装在DOM中,这意味着如果测试全部使用相同的DOM,则它们可能会相互影响。在编写测试时,请记住这一点,并在必要时使用.unmount()清理之类的工具。

describe('Enzyme Mount', function () {  
  //测试删除是否起作用 
  it('Delete button',function () {    
    let app = mount(<App/>);      
    let totalLength = app.find("li").length;
    app.find("button.delete").at(0).simulate('click');
    expect(app.find("li").length).to.equal(totalLength-1);  
  });
});
1
2
3
4
5
6
7
8
9

在这些测试方法中 穿插了常用的Enzyme的API方法

.get(index):返回指定位置的子组件的DOM节点
.at(index):返回指定位置的子组件
.text():返回当前组件的文本内容
.html():返回当前组件的HTML代码形式
.props():返回根组件的所有属性
.prop(key):返回根组件的指定属性
.state([key]):返回根组件的状态
1
2
3
4
5
6
7

更多完整的api请看这里

Thomas: 11/13/2019, 7:10:29 PM