2017-12-29 53 views
0

일부 코드를 단위 테스트에 React Test Utilities 사용하고 있습니다. renderIntoDocument을 호출하여 사용자 지정 구성 요소를 렌더링 한 다음 findDOMNode을 사용하여 렌더링 된 내용을 테스트합니다. 제가 실행하고있는 문제는 상태를 업데이트하고 단위 테스트의 컨텍스트 내에서 다시 렌더링을 효과적으로 트리거하는 방법을 모르겠다는 것입니다.React DOM을 사용하여 단위 테스트에서 상태 변경을 트리거하는 방법은 무엇입니까?

는 여기에 몇 가지 예제 코드입니다 - 코드 주석에주의 :

import React from 'react'; 
import ReactDOM from 'react-dom'; 
import TestUtils from 'react-dom/test-utils'; 
import MyCustomComponent from '../../app/components/MyCustomComponent'; 

describe('My Test Suite',() => { 
    let component, node; 
    test('verify state change',() => { 
     const items = [{'value': '1'}]; 
     component = TestUtils.renderIntoDocument(
      <MyCustomComponent items={items} /> 
     ); 
     node = ReactDOM.findDOMNode(component); 
     expect(node.querySelector('input[type=text]').value).toEqual('1'); 
     component.state.items = [{'value': '2'}]; 
     // do something here to trigger a re-render? 
     expect(node.querySelector('input[type=text]').value).toEqual('2'); 
    }); 
}); 

불행하게도 단순히 아무것도하지 않는 상태 변수를 변경 보인다. 그리고 정의되지 않은 것 같습니다 때문에 component.componentWillReceiveProps() 전화 할 수 없습니다.

동일한 구성 요소가 실제로 새로운 구성 요소로 대체되는 대신 해당 렌더링 기능을 호출하기를 원합니다. 그 이유는 구성 요소가 this.state 대신 this.props 대신에 버그를 발견했기 때문이며, 테스트에서는 항상 초기 값이 아닌 상태의 데이터를 사용하고 있음을 보여주기를 원합니다.

+0

ReactDOM.render (, node)를 이미 사용해 보았습니까? 구성 요소를 강제로 렌더링 하시겠습니까? –

+0

@MarouenMhiri는 컴포넌트의 새로운 인스턴스를 효과적으로 만들지 않을까요? (기존 인스턴스를 다시 렌더링하는 대신) – SoaperGEM

+0

구성 요소를 다시 마운트하지 않고 업데이트합니다! 나는 이것이 당신이 찾고있는 것이라고 생각합니다. –

답변

2

Enzyme AirBnb에서 제공하는 유틸리티입니다. the dependencies을 설치해야하지만 간단하게 구성 할 수 있습니다. 그런 다음 구성 요소 인스턴스에서 Enzyme's setState method으로 간단하게 전화 할 수 있습니다. 중요한 참고 사항 -이 경우의 "구성 요소 인스턴스"는 shallow rendered component입니다. 코드는 다음과 같을 것이다 :

import React from 'react'; 
import MyCustomComponent from '../../app/components/MyCustomComponent'; 
import { shallow, configure } from 'enzyme'; 
import Adapter from 'enzyme-adapter-react-16'; 

// configure your adapter 
configure({ adapter: new Adapter() }); 

describe('My Test Suite',() => { 

    test('verify state change',() => { 
     const items = [{'value': '1'}]; 
     const wrapper = shallow(<MyCustomComponent items={items} />); 

     // find your shallow rendered component and check its value 
     expect(wrapper.find('input[type="text"]').value).toEqual('1'); 

     // set the state of the component 
     wrapper.setState({ items: [{'value': '2'}] }); 

     // state should be updated, make sure its value was properly set 
     expect(wrapper.find('input[type="text"]').value).toEqual('2'); 
    }); 
}); 

이 모든 제대로 구성 요소에 state를 사용하고 있다고 가정합니다. 귀하의 경우 itemsprop으로 전달 된 것으로 보입니다. props을 복사하여 state으로 설정하는 경우 전략을 다시 생각해 볼 수 있습니다. 어쨌든이 접근법은 실제 작업에서 state 업데이트와 동일해야합니다. 즉, 구성 요소를 마운트 해제하고 다시 마운트하지 않고 동일한 구성 요소 인스턴스에서 작동하고 있어야합니다. 희망이 도움이됩니다.

+0

이것은 정말로 유망 해 보입니다! 불행히도 나는 그것을 실행하려고 할 때 즉시이 에러를 만나게된다.'선택자를 파싱하지 못했습니다 : input [type = text]'효소가 사소한 선택자 표현식을 넘어선 아무것도 지원하지 않습니까? – SoaperGEM

+0

효소가 확실히 이것을 지원합니다 - 여기 ' 선택자에 대한 API 참조 : http://airbnb.io/enzyme/docs/api/selector.html –

+0

업데이트 된 샘플 코드를 사용해보십시오. 나는 그것을'wrapper.find ('input [type = "text"]')'로 정정했다. 그 큰 따옴표는 중요합니다! 행운을 빕니다! –