Enzyme

Since the enzyme can make us get easier to update to new version of React and make our test code more lean and maintainable
You'd better not use props() to get props from component, because Enzyme document said that only the root component can get props by the function. We can use chai-moment to do the assertion

Render a component

Please use methods in require('test/unit/helpers/renderHelpers') to render component, do not use enzyme directly, this gives us the flexibility to handle the memory issue.

  • Currently the renderHelper.js is only on the spike branch. And will make a pr soon.
  • You can also checkout this spike branch to see how we change the existing tests to enzyme.

UI component

const {mount} = require('test/unit/helpers/renderHelpers')

const wrapper = mount(<div></div>);

You can specify the DOM node you want to mount on by provide the second argument:

const container = document.createElement('div');

const wrapper = mount(<div></div>, {
  attachTo: container
});

enzyme also provide shallow render, but I suggest to use mount for keeping things consistant.

Page or component with route dependency

const {mountWithRouteContext} = require('test/unit/helpers/renderHelpers')

const wrapper = mount(<YourPage/>);

Wrapper methods of enzyme

When you call the render method we metioned before, instead of return a ReactComponent, now we returns a wrapper provide by enzyme.
Here I would like to introduce some most useful methods. And please check the document for more information.

find a child component

find

the powerful find method can find a node with powerful Enzyme Selector which support CSS selector and component constructor.

const wrapper = mount(
  <div>
    <span className='foo'>
      <span className='bar'>
        <Icon type='baz'/>
      </span>
    </span>
  </div>);

//by jQuery selector
const fooWrapper = wrapper.find('.foo')

//find also returns a wrapper, so it support chaining call
const barWrapper = wrapper.find('.foo').find('.bar')

//by Component type
const iconWrapper = wrapper.find(Icon)

ref

class Foo extends React.Component {
  render() {
    return (
      <div>
        <span ref="firstRef" amount={2}>First</span>
        <span ref="secondRef" amount={4}>Second</span>
        <span ref="thirdRef" amount={8}>Third</span>
      </div>
    );
  }
}

const wrapper = mount(<Foo />);
expect(wrapper.ref('secondRef').prop('amount')).to.equal(4);

at/childAt

The wrapper in enzyme is just like jQuery object. so it might have multiple components inside, the at and childAt can find a node in the current wrapper by index passed in
Note : the index is zero-based

const wrapper = mount(
  <ul>
    <li/>
    <li/>
    <li/>
  </ul>
)

//find the first li
wrapper.find('li').at(0)
wrapper.find('li').first()

//find the third li node
wrapper.find('li').at(2)
wrapper.find('li').last()
wrapper.childAt(2)

instance

You can get the ReactComponent instance, but it's only available for the wrapper of root node (the node passed into mount())

wrapper.state() in enzyme is only available for root component
It's useful when you want to stub a method like transitionTo

buttonLink.instance().transitionTo = spy();

//This is unvaliable! .instance is only for the root node
buttonLink.find('span').instance()

simulate

To simulate events:

const wrapper = mount(<div/>)
wrapper.simulate('click')

Assertion

  • suggest to use chai and chai-enzyme to do the assertion instead of should.js, we've created some customized assert method like containText work with should.js before, but I think chai-enzyme cover more scenarioes.
  • highly suggest you to check the document of chai-enzyme when you don't know how to do the assertion, and below are the most common cases we will meet

A node is shown

const wrapper = mount(<div><span></span></div>);

expect(wrapper.find('span')).to.be.present();
expect(wrapper.find('span')).to.exist; //exist is an alias

expect(wrapper.find('ul')).to.not.be.present();
expect(wrapper.find('ul')).to.not.exist;

Have or contain some text

const wrapper = mount(
  <div id='root'>
    <span id='child'>Test</span>
  </div>
) 

expect(wrapper.find('#child')).to.have.text('Test')

expect(wrapper.find('#child')).to.contain.text('Te')

expect(wrapper.find('#child')).to.not.have.text('Other text')

Have some prop or className

const wrapper = mount(
  <div>
    <ul>
      <li><User index={1} user={{name: 'Jane'}} /></li>
      <li><User index={2} /></li>
    </ul>
  </div>
) 

expect(wrapper.find(User).first()).to.have.prop('index')
expect(wrapper.find(User).first()).to.not.have.prop('invalid')


expect(wrapper.find(User).first()).to.have.prop('index', 1)
expect(wrapper.find(User).first()).to.not.have.prop('index', 2)

expect(wrapper.find(User).first()).to.have.prop('index').equal(1)
expect(wrapper.find(User).first()).to.have.prop('user').deep.equal({name: 'Jane'})
And if you want to check the className, here is a better way: 
const wrapper = mount(
  <div className='root top'>
    <span className='child bottom'>test</span>
  </div>
)

expect(wrapper.find('span')).to.have.className('child')
expect(wrapper.find('span')).to.not.have.className('root')
to.be.true;
to.be.null;
to.have.lengthOf(2);
to.have.deep.property(‘response.title’, ’sdfdgd')
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值