React 컴포넌트에서 프로펠러 업데이트를 테스트하는 방법
React 구성 요소 프로펠러 업데이트를 테스트하는 올바른 방법은 무엇입니까?
여기 제 시험기구가 있습니다.
describe('updating the value', function(){
var component;
beforeEach(function(){
component = TestUtils.renderIntoDocument(<MyComponent value={true} />);
});
it('should update the state of the component when the value prop is changed', function(){
// Act
component.props.value = false;
component.forceUpdate();
// Assert
expect(component.state.value).toBe(false);
});
});
정상적으로 동작하고 테스트에 합격하지만 리액트 경고 메시지가 표시됩니다.
'Warning: Dont set .props.value of the React component <exports />. Instead specify the correct value when initially creating the element or use React.cloneElement to make a new element with updated props.'
테스트하려는 것은 속성 업데이트일 뿐 다른 속성을 가진 요소의 새 인스턴스를 만드는 것은 아닙니다.이 숙박업소를 갱신할 수 있는 더 좋은 방법이 있을까요?
AirBnB의 효소 라이브러리는 이 질문에 대한 우아한 해결책을 제공합니다.
얕은 래퍼 또는 jsdom 래퍼에서 호출할 수 있는 setProps 메서드를 제공합니다.
it("Component should call componentWillReceiveProps on update", () => {
const spy = sinon.spy(Component.prototype, "componentWillReceiveProps");
const wrapper = shallow(<Component {...props} />);
expect(spy.calledOnce).to.equal(false);
wrapper.setProps({ prop: 2 });
expect(spy.calledOnce).to.equal(true);
});
동일한 컨테이너 노드에서 다른 소품으로 요소를 다시 렌더링하는 경우 다시 마운트되는 대신 업데이트됩니다.React.render를 참조하십시오.
당신의 경우,ReactDOM.render대신 직접TestUtils.renderIntoDocument후자는 호출될 때마다 새로운 컨테이너 노드를 생성하고, 따라서 새로운 컴포넌트도 만듭니다.
var node, component;
beforeEach(function(){
node = document.createElement('div');
component = ReactDOM.render(<MyComponent value={true} />, node);
});
it('should update the state of the component when the value prop is changed', function(){
// `component` will be updated instead of remounted
ReactDOM.render(<MyComponent value={false} />, node);
// Assert that `component` has updated its state in response to a prop change
expect(component.state.value).toBe(false);
});
주의: 이것이 실제로 소품을 바꾸지는 않습니다.
하지만 제게는 제 논리를 시험해보고 싶었어요componentWillReceiveProps그래서 전화드렸습니다.myComponent.componentWillReceiveProps(/*new props*/)직접적으로.
소품이 바뀌었을 때 리액트가 메서드를 호출하는지, 소품이 바뀌었을 때 리액트가 소품을 세팅하는지 테스트할 필요가 없었다.그냥 소품이 전달된 것과 다르면 애니메이션이 트리거된다.
또, 테스트·라이브러리의 회답은 이쪽에서 찾을 수 없었습니다만, 이 호에는 다음과 같은 예가 기재되어 있습니다.
const {container} = render(<Foo bar={true} />)
// update the props, re-render to the same container
render(<Foo bar={false} />, {container})
또는, 현재는 테스트 라이브러리에서도 같은 것을 실현하는 방법을 제공하고 있습니다.
이것은 오래된 질문입니다만, 다른 사람이 우연히 발견했을 경우에 대비해, 다음의 설정이 도움이 되었습니다.
it('updates component on property update', () => {
let TestParent = React.createClass({
getInitialState() {
return {value: true};
},
render() {
return <MyComponent value={this.state.value}/>;
}
});
component = TestUtils.renderIntoDocument(<TestParent/>);
component.setState({value: false});
// Verification code follows
});
그러면 React가 일반적인 컴포넌트 업데이트를 실행합니다.
다음은 ReactDOM.render를 사용하지만 함수의 (사용하지 않는) 반환값에 의존하지 않는 솔루션을 보여 줍니다.대신 콜백(ReactDOM.render에 대한 세 번째 인수)을 사용합니다.
브라우저에서 테스트하지 않는 경우 jsdom을 설정합니다.
var jsdom = require('jsdom').jsdom;
var document = jsdom('<!doctype html><html><body><div id="test-div"></div></body></html>');
global.document = document;
global.window = doc.defaultView;
비동기 콜백을 사용한 react-dom 렌더를 사용한 테스트:
var node, component;
beforeEach(function(done){
node = document.getElementById('test-div')
ReactDOM.render(<MyComponent value={true} />, node, function() {
component = this;
done();
});
});
it('should update the state of the component when the value prop is changed', function(done){
// `component` will be updated instead of remounted
ReactDOM.render(<MyComponent value={false} />, node, function() {
component = this;
// Assert that `component` has updated its state in response to a prop change
expect(component.state.value).toBe(false);
done();
});
});
효소를 사용하여 구성요소를 마운트하고 여기에 소품을 추가할 수 있습니다.
import React form 'react';
import component;
import {configure, mount} form 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import {expect} from 'chai';
configure({adapter: new Adapter()});
describe('Testing component', () => {
let wrapper;
beforeEach(() => {
component = mount(<MyComponent value={false} />);
});
it('should update the state of the component when the value prop is changed', function(){
expect(component.props().children.props.value).toBe(false);
});
둘다요.TestUtils.renderIntoDocument그리고.ReactDOM.render에서 반환된 값을 사용합니다.ReactDOM.render. React 문서에 따르면:
ReactDOM.render()는 현재 루트 ReactComponent 인스턴스에 대한 참조를 반환합니다.그러나 이 반환값을 사용하는 것은 레거시이므로 향후 React 버전에서 구성 요소를 비동기식으로 렌더링할 수 있으므로 사용하지 않는 것이 좋습니다.루트 React Component 인스턴스에 대한 참조가 필요한 경우 권장되는 솔루션은 콜백 참조를 루트 요소에 연결하는 것입니다.
이 조언을 받아들여 다음과 같이 하면 어떨까요?
let component, node;
const renderComponent = (props = {}) => {
ReactDOM.render(<MyComponent ref={r => component = r} {...props} />, node);
}
beforeEach(function(){
node = document.createElement('div');
renderComponent({value: true}, node);
});
it('should update the state of the component when the value prop is changed', function(){
// `component` will be updated instead of remounted
renderComponent({value: false}, node);
// Assert that `component` has updated its state in response to a prop change
expect(component.state.value).toBe(false);
});
방법(with)ReactDOM.render(<MyComponent ref=...는 HOC
언급URL : https://stackoverflow.com/questions/30614454/how-to-test-a-prop-update-on-react-component
'it-source' 카테고리의 다른 글
| WordPress 사용자 지정 게시물 목록을 표시하려면 어떻게 해야 합니까? (0) | 2023.04.01 |
|---|---|
| JS를 테스트하기 위해 레일 각도 프로젝트를 설정하려면 어떻게 해야 합니까? (0) | 2023.04.01 |
| 내 WordPress 플러그인에서 파일에 쓰기 (0) | 2023.04.01 |
| 사용 가능한 경우 서버 동기화를 사용하여 Angular.js 앱을 오프라인으로 만드는 방법 (0) | 2023.04.01 |
| Angular를 사용하여 URL을 프로그래밍 방식으로 작성하는 방법JS (0) | 2023.04.01 |