Enzyme - arthur791004/notes GitHub Wiki

Why

  • 官方的 TestUtils 非常之難用,封裝了該套件
  • 擁有類似 jQuery 的 selector API,方便撰寫測試
  • 提供 simulate 函數來模擬事件的觸發
  • 提供接口讓我們獲取和操作 component 的 state 和 props
  • enzyme-to-json 可在生成 snapshot 時使用 toJson 進行格式化,方便閱讀

Basic

Shallow

  • 封裝官方的 shallow rendering
  • 指渲染第一層,不渲染子元件
  • 速度快
  • 不管 child component 的行為,測試重點只是 component 本身

Mount

  • Full rendering
  • 真實的 DOM 節點
  • 想要測試與 DOM 的互動與後續產生的變化 (如 click 後刪除一個 list 的項目)
  • 想要測試完整的生命週期

Render

  • 類似 shallow,但使用 Cheerio 的 HTML Parser
  • 不只渲染一層
  • API 與 shallow 基本一致
  • When
    • useful to constrain yourself to testing a component as a unit
    • ensure that your tests aren't indirectly asserting on behavior of child components
  • Usage
    import { shallow } from 'enzyme';
    
    describe('<MyComponent />', () => {
      it('should render three <Foo /> components', () => {
        const wrapper = shallow(<MyComponent />);
        expect(wrapper.find(Foo)).to.have.length(3);
      });
    });
    
  • API
    • find
    • unmount
    • text
    • html: Returns a static HTML rendering of the current node
    • state: Returns the state of the root component
    • context: Returns the context of the root component
    • props: Returns the props of the current node
    • simulate: Simulates an event on the current node
    • setState
    • setProps
    • setContext
    • ...
  • When
    • you have components that may interact with DOM APIs
    • may require the full lifecycle in order to fully test the component (i.e., componentDidMount etc.)
  • Usage
    import { mount } from 'enzyme';
    import Foo from './Foo';
    
    describe('<Foo />', () => {
      it('allows us to set props', () => {
        const wrapper = mount(<Foo bar="baz" />);
        expect(wrapper.props().bar).to.equal('baz');
        wrapper.setProps({ bar: 'foo' });
        expect(wrapper.props().bar).to.equal('foo');
      });
    });
    
  • API
    • ...
  • When
    • render react components to static HTML and analyze the resulting HTML structure
  • Usage
    import React from 'react';
    import { render } from 'enzyme';
    import PropTypes from 'prop-types';
    
    describe('<Foo />', () => {
      it('renders three `.foo-bar`s', () => {
        const wrapper = render(<Foo />);
        expect(wrapper.find('.foo-bar')).to.have.length(3);
      });
    });
    
  • API
    • ...
  • Selectors
    • class syntax (.foo, .foo-bar, etc.)
    • tag syntax (input, div, span, etc.)
    • id syntax (#foo, #foo-bar, etc.)
    • prop syntax ([htmlFor="foo"], [bar], [baz=1], etc.);
    • others
      • .foo .bar
      • .foo > .bar
      • .foo + .bar
      • .foo ~ .bar
      • .foo input
  • Example
    const wrapper = mount((
      <div>
        <span foo={3} bar={false} title="baz" />
      </div>
    ));
    
    wrapper.find('[foo=3]');
    wrapper.find('[bar=false]');
    wrapper.find('[title="baz"]');
    

Reference

⚠️ **GitHub.com Fallback** ⚠️