Airbnb의 효소, Jest, Babel을 사용하여 반응 테스트를 진행하다
                                            
                                                
                                                
                                                
                                                
                                                
                                                 95352 단어  reacttestingwebdevjavascript
                    
여보세요, 점원들, 안녕하세요!
네, 점원들, 우선 Jest를 처음부터 시작하는 효소를 설정해야 합니다.그래서 당신은 우리가 어떤 모듈이나 소프트웨어 패키지를 사용할지 알 수 있습니다.
데스크톱의 명령줄에서 이 작업을 수행합니다.
  md testing-with-enzyme && cd testing-with-enzyme
&&- 첫 번째 명령이 오류를 일으키지 않으면 두 번째 명령을 실행합니다
cd 효소 테스트 - 현재 디렉터리를 효소 테스트로 변경
  npm init --y && npm i -D @babel/preset-env @babel/preset-react 
  @babel/plugin-proposal-class-properties @types/jest jest
  enzyme enzyme-adapter-react-16 && npm i -P react react-dom
 type nul > babel.config.js && type nul > jest.config.js && md Tests && md components
우리 바베타.구성js 파일.
module.exports = {
  presets: ['@babel/preset-env', '@babel/preset-react'],
  plugins: ['@babel/plugin-proposal-class-properties']
}
module.exports = {
  rootDir: '.',
  displayName: {
    name: 'enzyme-setup',
    color: 'blue'
  },
  runner: 'jest-runner',
  verbose: true,
  errorOnDeprecated: true,
  roots: ['./Tests'],
  moduleFileExtensions: ['js', 'jsx'],
  setupFilesAfterEnv: ['<rootDir>Tests/setupTest.js']
}
import { configure } from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'
configure({
  adapter: new Adapter()
})
 
 components 폴더에 4개의 파일을 만듭니다.
  type nul > App.js && type nul > Form.js && type nul > Header.js && type nul > List.js
import React from 'react'
export default function Header({ message, handleToggleTheme, theme }) {
  return (
    <div className="header">
      <h1>{message}</h1>
      <button className="right" onClick={handleToggleTheme}>
        <i className={theme}></i>
      </button>
    </div>
  )
}
import React from 'react'
export default function Form({ handleChange, value, handleClick }) {
  return (
    <div className="form">
      <input
        className="form-control"
        type="text"
        onChange={handleChange}
        value={value}
      />
      <button className="btn" onClick={handleClick}>
        Submit
      </button>
    </div>
  )
}
import React from 'react'
export default function List({ items }) {
  return (
    <ul className="list">
      {items.map(item => (
        <li className="list-item" key={item}>{item}</li>
      ))}
    </ul>
  )
}
import React, { Component } from 'react'
import Header from './Header'
import List from './List'
import Form from './Form'
export default class App extends Component {
  state = {
    listItem: '',
    items: [],
    isDarkTheme: false
  }
  handleChange = ({ target: { value } }) => {
    this.setState({
      listItem: value
    })
  }
  handleClick = () => {
    this.setState({
      items: [...this.state.items, this.state.listItem],
      listItem: ''
    })
  }
  handleToggleTheme = () => {
    this.setState({
      isDarkTheme: !this.state.isDarkTheme
    })
  }
  render() {
    const theme = this.state.isDarkTheme ? 'dark' : 'light'
    return (
      <div className={theme}>
        <Header
          theme={theme}
          message={this.props.message}
          handleToggleTheme={this.state.handleToggleTheme}
        />
        <Form
          handleChange={this.state.handleChange}
          value={this.state.listItem}
          handleClick={this.state.handleClick}
        />
        <List items={this.state.items} />
      </div>
    )
  }
}
App.defaultProps = {
  message: 'Hello World'
}
import React from 'react'
import App from '../components/App'
import Header from '../components/Header'
import Form from '../components/Form'
import List from '../components/List'
import { shallow, mount } from 'enzyme'
describe('Test App component', () => {
  let wrapper;
  beforeAll(() => {
    wrapper = shallow(<App />)
  })
  it('should not return an error', () => {
    expect(wrapper).toMatchSnapshot()
    console.log(wrapper.debug())
  })
})
 npm t
얕은 렌더링과 전체 설치 렌더링 사이에는 어떤 차이가 있습니까?
shallow와 mount는 매우 유용한 디버깅 방법을 제공합니다.
색인을 업데이트해 보십시오.테스트js 파일이 이렇게 보입니다.
import React from 'react'
import App from '../components/App'
import Header from '../components/Header'
import Form from '../components/Form'
import List from '../components/List'
import { shallow, mount } from 'enzyme'
describe('Test App component', () => {
  let shallowWrapper, mountWrapper;
  beforeAll(() => {
    shallowWrapper = shallow(<App />)
    mountWrapper = mount(<App />)
    console.log(shallowWrapper)
    console.log(mountWrapper)
  })
})
디버깅 방법을 사용하여 구성합니다.
첫 번째 컨트롤러.일지는 이렇게 보인다.
 console.log Tests/index.test.js:12
    <div className="light">
      <Header theme="light" message="Hello World" handleToggleTheme={[Function]} 
        />
      <Form handleChange={[Function]} value="" handleClick={[Function]} />
      <List items={{...}} />
    </div>
  console.log Tests/index.test.js:13
    <App message="Hello World">
      <div className="light">
        <Header theme="light" message="Hello World" handleToggleTheme={[Function]}>
          <div className="header">
            <h1>
              Hello World
            </h1>
            <button className="right" onClick={[Function]}>
              <i className="light" />
            </button>
          </div>
        </Header>
        <Form handleChange={[Function]} value="" handleClick={[Function]}>
          <div className="form">
            <input className="form-control" type="text" onChange={[Function]} value="" />
            <button className="btn" onClick={[Function]} />
          </div>
        </Form>
        <List items={{...}}>
          <ul className="list" />
        </List>
      </div>
    </App>
효소가 우리에게 제공하는 유용한 방법.
at(인덱스: 번호)
주어진 색인에 따라 포장기 요소를 되돌려줍니다.
우리 프로그램 구성 요소에서shallow와mount의 차이를 사용합니다.
  it('should have an "App" component "at" index of 0', () => {
    let wrapper = shallow(<App />);
    expect(wrapper.at(0).type()).toBe(App);
  });
  it('should return an App', () => {
    let wrapper = mount(<App />);
    expect(wrapper.at(0).type()).toBe(App)
  });
childAt(인덱스: 숫자)
지정된 인덱스에서 하위 레벨의 새 패키지를 되돌려줍니다.
  it('should have a child component of type "Header" at "index" of 0', () => {
    let wrapper = shallow(<App />);
    expect(wrapper.childAt(0).type()).toBe(Header);
  });
  it('should have a child element of type "div" at "index" of 0', () => {
    let wrapper = mount(<App />);
    expect(wrapper.childAt(0).type()).toBe('div')
  });
찾기(선택기: EnzymeSelector)
기본적으로 주어진 선택기와 일치하는 모든 노드를 찾습니다.
선택기.
find ('div') = 현재 포장에 있는 모든'div'요소를 찾습니다.
find ('div.something') = 현재 패키지에서'something'클래스가 있는'div'요소를 찾습니다.
오키나와의'div'의 직계 자녀
   function App({ children }){
     return (
       <div>
           {children}
        </div>
     )
   }   
   function SomeComponent(){
      return (
        <div>
         <h1>
            Hi!
         </h1>
        </div>
      )
   }
   it('should have length of "1" when finding "SomeComponent" comp', () => {
    const wrapper = shallow(<App>
         <SomeComponent />
     </App>
     )
    expect(wrapper.find(SomeComponent)).toHaveLength(1);
   });
최근(선택기: EnzymeSelector)
선택기와 일치하는 최근 상위 레벨을 찾습니다.그것은 자신부터 모든 노드를 두루 돌아다닌다.
  it('should have an h1 with a text of "Hello World"', () => {
    let wrapper = shallow(<App />);
    expect(wrapper.find(Header).closest('div.light')).toHaveLength(1);
  });
  it('should have a parent element of "div" with a class of "light"', () => {
    let wrapper = mount(<App />);
    expect(wrapper.find(Header).closest('div.light')).toHaveLength(1);
  })
포함 (노드: 노드 | 노드 [])
포함된 패키지에 일치하는 하위 항목이 있는지 테스트합니다.
   it('should have a node of <Header /> and the right props', () => {
    let wrapper = shallow(<App />);
    expect(wrapper.contains(
      <Header theme="light" message="Hello World" handleToggleTheme= 
           {wrapper.instance().handleToggleTheme} />
    )).toBeTruthy();
  });
  it('should contain these two nodes', () => {
    const wrapper = mount(<App />);
    expect(wrapper.contains([
      <h1>Hi</h1>,
      <button className="right" onClick={wrapper.instance().handleToggleTheme}>
        <i className="light" />
      </button>
    ])).toBeTruthy();
  })
일치하는 모든 요소 포함 (노드: 노드 [])
현재 포장의 모든 노드와 일치해야 합니다.
 it('should have these two nodes when shallow mounting', () => {
   let wrapper = shallow(<App />);
    wrapper.setState({ listItem: '1' })
    expect(wrapper.containsAllMatchingElements(
      [
        <Form handleChange={wrapper.instance().handleChange} value="1" handleClick={wrapper.instance().handleClick} />,
        <Header theme="light" message="Hello World" handleToggleTheme={wrapper.instance().handleToggleTheme} />
      ]
    )).toBeTruthy();
  });
  it('should have these two nodes when mounting', () => {
    let wrapper = mount(<App />);
    expect(wrapper.containsAllMatchingElements([
      <h1>Hi</h1>,
      <button className="right" onClick={wrapper.instance().handleToggleTheme}>
        <i className="light" />
      </button>
    ])).toBeTruthy();
  })
this.setState({property: newValue}) . 이 테스트들은 반드시 통과해야 한다.containsAnyMatchingElements(노드: 노드 [])
현재 포장의 최소 노드와 일치해야 합니다.
  it('should this Form with the right props', () => {
    expect(wrapper.containsAnyMatchingElements(
      [
        <Form handleChange={wrapper.instance().handleChange} value="1" handleClick={wrapper.instance().handleClick} />,
      ]
    )).toBeTruthy();
  });
  it('should return true because the "i" element is right while "div" element is not the right structure', () =>{
    expect(wrapper.containsAnyMatchingElements([
      <div className="form">
      </div>,
      <i className="light" />
    ])).toBeTruthy();
  });
첫 번째 ()
동작은 (0)refer와 유사합니다.
hasClass (클래스: 문자열)
현재 노드에 className 속성이 있는지 확인하고 값을 확인하십시오.
   it('should have a class of "light"', () => {
    let wrapper = shallow(<App />);
    expect(wrapper.hasClass('light')).toBeTruthy();
   });
   it('should have a class of "form-control"', () => 
     wrapper = mount(<App />);  
    {
    expect(wrapper.find(Form).find('#form').childAt(0).hasClass('form-control')).toBeTruthy();
  })
html()
현재 포장된 원시 html 문자열을 되돌려줍니다.
   it('should return the correct string', () => {
    let wrapper = shallow(<App >);
    expect(wrapper.childAt(2).html()).toBe('<ul class="list"></ul>')
  });
  it('should have an element with an id of "form"', () => {
    let wrapper = mount(<App >);
    wrapper.setProps({ message: 'Hi' });
    expect(wrapper.find('h1').html()).toBe('<h1>Hi</h1>')
  })
인스턴스()
현재 패키지의 현재 클래스를 되돌려줍니다. 기능 구성 요소에서 사용할 때null을 되돌려줍니다.실례 방법은 루트 노드에서만 사용할 수 있다.
   it('should be an instance of App', () => {
    let wrapper = shallow(<App />);
    expect(wrapper.instance()).toBeInstanceOf(App);
  });
  it('should be an instance of App', () => {
    let wrapper = mount(<App />);
    expect(wrapper.instance()).toBeInstanceOf(App);
  });
호출(functionPropName)(...매개 변수)
  it('should have a prop of "value" with a value of "12344"', () => {
    let wrapper = shallow(<App />);
    wrapper.find(Form).invoke('handleChange')({ target: { value: '12344' } });
    expect(wrapper.find(Form).prop('value')).toBe('12344');
  });
  it('should truthy value of prop "isDarkTheme"', () => {
    let wrapper = mount(<App />);
    wrapper.find(Header).invoke('handleToggleTheme')()
    expect(wrapper.state('isDarkTheme')).toBeTruthy();
  })
   handleChange = ({ target: { value } }) => {
    this.setState({
      listItem: value
    })
  }
is(선택기: EnzymeSelector)
선택기가 현재 포장과 일치하는지 확인하십시오.
  it('should return false when checking with ".is"', () => {
    let wrapper = shallow(<App />);
    expect(wrapper.find(List).find('ul').is('.list')).toBeFalsy();
  });
  it('should return true when checking with ".is"', () => {
    let wrapper = mount(<App />);
    expect(wrapper.find(List).find('ul').is('.list')).toBeTruthy();
  });
shallow를 사용할 때의 원소 구조는 다음과 같다.
    <div className="light">
      <Header theme="light" message="Hello World" handleToggleTheme={[Function]} 
        />
      <Form handleChange={[Function]} value="" handleClick={[Function]} />
      <List items={{...}} />
    </div>
isEmptyRender()
현재 포장이
null 또는 false 로 되돌아오면true로 되돌아옵니다.
  it('should not be falsy because "App" does not return neither null or false', () => {
    let wrapper = shallow(<App />);
    expect(wrapper.isEmptyRender()).toBeFalsy();
  });
  it('should return "Nothing" literally', () => {
    class Nothing extends React.Component {
      render() {
        return (
          null
        )
      }
    }
    let wrapper = mount(<Nothing />);
    expect(wrapper.isEmptyRender()).toBeTruthy();
  });
키()
현재 포장된 키 값을 되돌려줍니다.
  it('should have a prop of items with a length of 2 and a key value of "japan"', () => {
    let wrapper = mount(<Form />);
    let form = wrapper.find(Form);
    form.invoke('handleChange')({ target: { value: 'okinawa' } });
    form.invoke('handleClick')();
    form.invoke('handleChange')({ target: { value: 'japan' } });
    form.invoke('handleClick')();
    expect(wrapper.find(List).prop('items')).toHaveLength(2);
    expect(wrapper.find(List).find('ul').childAt(1).key()).toBe('japan');
  });
마지막 ()
현재 선택한 포장에 기반한 마지막 노드를 되돌려줍니다.
  it('should return the last child type which is "List"', () => {
    let wrapper = shallow(<App />);
    expect(wrapper.children().last().type()).toBe(List);
  });
  it('should return the last child type which is "div"', () => {
    let wrapper = mount(<App />)
    expect(wrapper.children().last().type()).toBe('div');
  });
이름 ()
현재 패키지의 이름 을 반환합니다.
   it('should return a name with a value of "div"', () => {
    let wrapper = shallow(<App />);
    expect(wrapper.name()).toBe('div');
  });
  it('should return a name with a value of "App"', () => {
    let wrapper = mount(<App />);
    expect(wrapper.name()).toBe('App');
  });
필터(선택기: EnzymeSelector)
그것은 주어진 선택기에 따라 새로운 포장기를 되돌려준다.
  it('should have a prop of "item" with length of 3', () => {
    let wrapper = mount(<App />);
    let form = wrapper.find(Form);
    let values = ["ohio", "usa", "amawa"];
    values.forEach((value) => {
      form.invoke('handleChange')({ target: { value } });
      form.invoke('handleClick')();
    })
  expect(wrapper.find(List).find('ul li').filter('.list-item')).toHaveLength(3);
  });
});
도구()
현재 포장된prop 대상 되돌리기
  it('should have a prop "items" with a value of []', () => {
    let wrapper = shallow(<App />);
    expect(wrapper.find(List).props().items).toEqual([]);
  });
  it('should have a prop "message" with a value of "Hello World"', () => {
    let wrapper = mount(<App />);
    expect(wrapper.find(Header).props().message).toBe("Hello World");
  });
아이템(키: 문자열)
현재 패키지의 속성 값을 되돌려줍니다.
  it('should have a prop "items" with a value of []', () => {
    let wrapper = shallow(<App />);
    expect(wrapper.find(List).prop('items')).toEqual([]);
  });
  it('should have a prop "message" with a value of "Hello World"', () => {
    let wrapper = mount(<App />);
    expect(wrapper.find(Header).prop('message')).toBe("Hello World");
  });
setProps(newProps:any)
루트 노드의 새 아이템 대상을 설정합니다.루트 노드에서만 사용할 수 있습니다.
 it('should have an updated prop "message" with a value of "What the fun"', () => {
    let wrapper = mount(<App />);
    wrapper.setProps({ message: 'What the fun' })
    expect(wrapper.find(Header).prop('message')).toBe("What the fun");
  });
상태 설정(newState:any, callbackFunc:Function)
루트 노드의 새 상태 객체를 설정합니다.루트 노드에서만 사용할 수 있습니다.
  it('should have an updated prop "isDarkTheme" with a value of true', () => {
    let wrapper = mount(<App />);
    wrapper.setState({ isDarkTheme: true });
    expect(wrapper.state('isDarkTheme')).toBeTruthy();
  });
아날로그 (이벤트: 문자열,...args)
현재 패키지의 이벤트를 호출합니다.
  it('should have an updated value of "1234"', () => {
    let wrapper = mount(<App />);
    wrapper.find('input').simulate('change', { target: { value: '1234' } });
    expect(wrapper.state('listItem')).toBe('1234');
  });
상태 (키: 문자열)
상태 속성의 값을 되돌려줍니다.
  it('should a input with a value of "abc"', () => {
    let wrapper = shallow(<App />);
    wrapper.setState({ listItem: 'abc' });
    expect(wrapper.state('listItem')).toBe('abc');
  });
  it('should have an updated "message" prop with a value of "Hi"', () => {
    let wrapper = mount(<App />);
    wrapper.setProps({ message: 'Hi' });
    expect(wrapper.prop('message')).toBe('Hi');
  })
텍스트 ()
현재 포장된 텍스트를 되돌려줍니다.
  it('should a text of "Hello World"', () => {
    let wrapper = mount(<App />);
    expect(wrapper.find('h1').text()).toBe('Hello World');
  });
유형()
현재 포장의 유형을 되돌려줍니다.
   it('should return the App', () => {
    let wrapper = shallow(<App />);
    expect(wrapper.at(0).type()).toBe('div');
  }); 
  it('should return the App', () => {
    let wrapper = mount(<App />);
    expect(wrapper.at(0).type()).toBe(App);
  });
이 글을 읽어 주셔서 감사합니다.
좋은 하루 되세요.😃!.
                
                    
        
    
    
    
    
    
                
                
                
                
                    
                        
                            
                            
                            Reference
                            
                            이 문제에 관하여(Airbnb의 효소, Jest, Babel을 사용하여 반응 테스트를 진행하다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
                                
                                https://dev.to/macmacky/react-testing-with-airbnb-s-enzyme-jest-and-babel-4cok
                            
                            
                            
                                텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
                            
                            
                                
                                
                                 우수한 개발자 콘텐츠 발견에 전념
                                (Collection and Share based on the CC Protocol.)
                                
                                
                                우수한 개발자 콘텐츠 발견에 전념
                                (Collection and Share based on the CC Protocol.)
                            
                            
                        
                    
                
                
                
            
Reference
이 문제에 관하여(Airbnb의 효소, Jest, Babel을 사용하여 반응 테스트를 진행하다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/macmacky/react-testing-with-airbnb-s-enzyme-jest-and-babel-4cok텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
                                
                                
                                
                                
                                
                                우수한 개발자 콘텐츠 발견에 전념
                                (Collection and Share based on the CC Protocol.)